Repository: egzosn/pay-spring-boot-starter-parent Branch: dev Commit: eaa831e9c43e Files: 70 Total size: 245.1 KB Directory structure: gitextract_dvzawco3/ ├── .gitignore ├── LICENSE ├── README.md ├── doc/ │ └── sql/ │ └── merchant_pay.sql ├── pay-spring-boot/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── egzosn/ │ └── pay/ │ └── spring/ │ └── boot/ │ └── core/ │ ├── MerchantPayServiceManager.java │ ├── PayBuilder.java │ ├── PayConfigurerAdapter.java │ ├── PayServiceConfigurer.java │ ├── PayServiceManager.java │ ├── bean/ │ │ ├── MerchantPayOrder.java │ │ └── MerchantQueryOrder.java │ ├── builders/ │ │ ├── InMemoryMerchantDetailsServiceBuilder.java │ │ ├── JdbcMerchantDetailsServiceBuilder.java │ │ └── MerchantDetailsServiceBuilder.java │ ├── configurers/ │ │ ├── DefalutPayMessageConfigurer.java │ │ ├── MerchantDetailsServiceConfigurer.java │ │ └── PayMessageConfigurer.java │ ├── merchant/ │ │ ├── MerchantDetails.java │ │ ├── MerchantDetailsService.java │ │ ├── MerchantNotFoundException.java │ │ ├── PaymentPlatform.java │ │ ├── PaymentPlatformMerchantDetails.java │ │ ├── PaymentPlatformServiceAdapter.java │ │ └── bean/ │ │ ├── AliMerchantDetails.java │ │ ├── CommonPaymentPlatformMerchantDetails.java │ │ ├── FuiouMerchantDetails.java │ │ ├── PayPalV2MerchantDetails.java │ │ ├── PayoneerMerchantDetails.java │ │ ├── PaypalMerchantDetails.java │ │ ├── UnionMerchantDetails.java │ │ ├── WxMerchantDetails.java │ │ ├── WxV3MerchantDetails.java │ │ └── WxYouDianMerchantDetails.java │ ├── provider/ │ │ ├── CacheMerchantDetailsManager.java │ │ ├── InMemoryMerchantDetailsManager.java │ │ ├── JdbcMerchantDetailsManager.java │ │ ├── MerchantDetailsManager.java │ │ └── merchant/ │ │ └── platform/ │ │ ├── AliPaymentPlatform.java │ │ ├── FuiouPaymentPlatform.java │ │ ├── PaymentPlatforms.java │ │ ├── PayoneerPaymentPlatform.java │ │ ├── PaypalPaymentPlatform.java │ │ ├── PaypalV2PaymentPlatform.java │ │ ├── UnionPaymentPlatform.java │ │ ├── WxPaymentPlatform.java │ │ ├── WxV3CombinePaymentPlatform.java │ │ ├── WxV3PaymentPlatform.java │ │ ├── WxV3ProfitSharingPlatform.java │ │ └── YoudianPaymentPlatform.java │ └── utils/ │ └── SqlTools.java ├── pay-spring-boot-autoconfigue/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── egzosn/ │ │ └── pay/ │ │ └── spring/ │ │ └── boot/ │ │ └── autoconfigue/ │ │ └── PayAutoConfiguration.java │ └── resources/ │ └── META-INF/ │ └── spring.factories ├── pay-spring-boot-starter/ │ ├── pom.xml │ └── src/ │ └── main/ │ └── resources/ │ └── META-INF/ │ └── spring.providers ├── pay-spring-boot-starter-demo/ │ ├── pom.xml │ └── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── egzosn/ │ │ └── pay/ │ │ └── spring/ │ │ └── boot/ │ │ └── demo/ │ │ ├── PayApplication.java │ │ ├── config/ │ │ │ ├── MerchantPayServiceConfigurer.java │ │ │ ├── MyAliPaymentPlatform.java │ │ │ ├── handlers/ │ │ │ │ ├── AliPayMessageHandler.java │ │ │ │ └── WxPayMessageHandler.java │ │ │ └── interceptor/ │ │ │ └── AliPayMessageInterceptor.java │ │ └── controller/ │ │ └── PayMerchantController.java │ └── resources/ │ ├── ali/ │ │ ├── alipayCertPublicKey_RSA2.crt │ │ ├── alipayRootCert.crt │ │ ├── appCertPublicKey_2016080400165436.crt │ │ └── www.egzosn.com_私钥.txt │ └── application.yml └── pom.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Compiled class file *.class # Log file *.log # BlueJ files *.ctxt # Mobile Tools for Java (J2ME) .mtj.tmp/ # Package Files # *.jar *.war *.nar *.ear *.zip *.tar.gz *.rar # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2018 egan Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # 支付聚合spring boot组件 pay-spring-boot-starter 是一个基于spring-boot实现自动化配置的支付对接, **让你真正做到一行代码实现支付聚合**, 让你可以不用理解支付怎么对接,只需要专注你的业务 ### 特性 1. 项目第三方依赖极少,依托于spring boot与pay-java,项目精简,不用担心项目迁移问题 2. 一行代码解决配置,一行代码发起支付,一行代码处理回调并且业务与支付完全隔离 3. 项目扩展性极强极灵活,组件中暴露大量接口,实现对应接口重写加入spring容器即可覆盖全部功能 4. 引入pay-java具体支付组件即可激活某一支付功能,代码可以不用任何修改即可使用 --- 全能第三方支付对接pay-spring-boot-starter开发工具包.优雅的轻量级支付模块集成支付对接支付整合(微信,支付宝,银联,友店,富友,跨境支付paypal,payoneer(P卡派安盈)易极付)app,扫码,网页支付刷卡付条码付刷脸付转账服务商模式、支持多种支付类型多支付账户,支付与业务完全剥离,简单几行代码即可实现支付,简单快速完成支付模块的开发 #### 本项目在以下代码托管网站 * 码云:https://gitee.com/egzosn/pay-spring-boot-starter-parent * GitHub:https://github.com/egzosn/pay-spring-boot-starter-parent #### 软件架构 spring-boot pay-java-parent #### 本项目基础实现 pay-java-parent 全能第三方支付对接Java开发工具包.优雅的轻量级支付模块集成支付对接支付整合(微信,支付宝,银联,友店,富友,跨境支付paypal,payoneer(P卡派安盈)易极付)app,扫码,网页支付刷卡付条码付刷脸付转账服务商模式、支持多种支付类型多支付账户,支付与业务完全剥离,简单几行代码即可实现支付,简单快速完成支付模块的开发,可轻松嵌入到任何系统里 目前仅是一个开发工具包(即SDK) * 码云:https://gitee.com/egzosn/pay-java-parent * GitHub:https://github.com/egzosn/pay-java-parent #### 使用教程 1. 引入 pay-spring-boot-starter ```xml com.egzosn pay-spring-boot-starter 1.0.5 ``` 2. 引入 你需要对接的基于`pay-java-parent`支付开发包,具体支付模块 "{module-name}" 为具体的支付渠道的模块名 pay-java-ali,pay-java-wx等 ```xml com.egzosn {module-name} 2.14.9 ``` 3. 编写一个基于com.egzosn.pay.spring.boot.core.PayServiceConfigurer的子类 ``` 3.1. 并将其加入spring容器中 3.2. 对PayServiceConfigurer的子类所实现的方法进行配置数据来源,目前提供两种方式`jdbc`与`inMemory` ``` 4. 使用: 在你需要用到的类中注入 `com.egzosn.pay.spring.boot.core.MerchantPayServiceManager` 这个类是一个支付相关的操作类,拿到该类的引用即可对任意支付进行操作 #### 使用案例详情查看[pay-spring-boot-starter-demo](pay-spring-boot-starter-demo?dir=1&filepath=pay-spring-boot-starter-demo) ###### 支付教程 * [基础模块支付宝微信讲解](https://gitee.com/egzosn/pay-java-parent/wikis/Home) * [微信V3,查看demo/WxV3PayController](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-demo/) * [微信合并支付,查看demo/WxV3CombinePayController](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-demo/) * [微信分账,查看demo/WxV3ProfitSharingController](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-demo/) * [银联](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-union?dir=1&filepath=pay-java-union) * [payoneer](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-payoneer?dir=1&filepath=pay-java-payoneer) * [paypal,查看demo/PayPalV2PayController](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-demo/) * [友店微信](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-wx-youdian?dir=1&filepath=pay-java-youdian) * [富友](https://gitee.com/egzosn/pay-java-parent/blob/develop/pay-java-fuiou?dir=1&filepath=pay-java-fuiou) * [自定义支付宝商户/MyAliPaymentPlatform](pay-spring-boot-starter-demo?dir=1&filepath=pay-spring-boot-starter-demo) 作者公众号 ![公众号](https://gitee.com/egzosn/pay-java-parent/raw/develop/pay-java-demo/src/main/webapp/gzh.png "gzh.png") E-Mail:egan@egzosn.com **QQ群:** 1. pay-java(1群): 542193977(已满) 2. pay-java(2群):766275051 微信群: 加我前拜托伸个小手关注公众号 ![微信群](https://egzosn.gitee.io/pay-java-parent/wx.jpg "wx.jpg") #### 参与贡献 1. Fork 本项目 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request 也感谢各大友友同学帮忙进行接口测试 非常欢迎和感谢对本项目发起Pull Request的同学,不过本项目基于git flow开发流程,因此在发起Pull Request的时候请选择develop分支。 ================================================ FILE: doc/sql/merchant_pay.sql ================================================ CREATE DATABASE merchant_pay; USE `merchant_pay`; DROP TABLE IF EXISTS `merchant_details`; CREATE TABLE `merchant_details` ( `details_id` char(32) NOT NULL COMMENT '列表id', `pay_type` varchar(16) NOT NULL COMMENT '支付类型(支付渠道) 详情查看com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform对应子类,aliPay 支付宝, wxPay微信..等等', `appid` varchar(32) DEFAULT NULL COMMENT '应用id', `mch_id` varchar(32) DEFAULT NULL COMMENT '商户id,商户号,合作伙伴id等等', `cert_store_type` varchar(16) DEFAULT NULL COMMENT '当前面私钥公钥为证书类型的时候,这里必填,可选值:PATH,STR,INPUT_STREAM,CLASS_PATH,URL', `key_private` mediumtext COMMENT '私钥或私钥证书', `key_public` mediumtext COMMENT '公钥或公钥证书', `key_cert` varchar(20480) DEFAULT NULL COMMENT 'key证书,附加证书使用,如SSL证书,或者银联根级证书方面', `key_cert_pwd` varchar(32) DEFAULT NULL COMMENT '私钥证书或key证书的密码', `notify_url` varchar(256) DEFAULT NULL COMMENT '异步回调', `return_url` varchar(256) DEFAULT NULL COMMENT '同步回调地址,大部分用于付款成功后页面转跳', `sign_type` varchar(16) NOT NULL COMMENT '签名方式,目前已实现多种签名方式详情查看com.egzosn.pay.common.util.sign.encrypt。MD5,RSA等等', `seller` varchar(32) DEFAULT NULL COMMENT '收款账号,暂时只有支付宝部分使用,可根据开发者自行使用', `sub_app_id` varchar(32) DEFAULT NULL COMMENT '子appid', `sub_mch_id` varchar(32) DEFAULT NULL COMMENT '子商户id', `input_charset` varchar(16) NOT NULL COMMENT '编码类型,大部分为utf-8', `is_test` tinyint(1) NOT NULL COMMENT '是否为测试环境: 0 否,1 测试环境', PRIMARY KEY (`details_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `merchant_details`(`details_id`,`pay_type`,`appid`,`mch_id`,`cert_store_type`,`key_private`,`key_public`,`key_cert`,`key_cert_pwd`,`notify_url`,`return_url`,`sign_type`,`seller`,`sub_app_id`,`sub_mch_id`,`input_charset`,`is_test`) values ('1','aliPay','2016080400165436','2088102169916436',NULL ,'MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKroe/8h5vC4L6T+B2WdXiVwGsMvUKgb2XsKix6VY3m2wcf6tyzpNRDCNykbIwGtaeo7FshN+qZxdXHLiIam9goYncBit/8ojfLGy2gLxO/PXfzGxYGs0KsDZ+ryVPPmE34ZZ8jiJpR0ygzCFl8pN3QJPJRGTJn5+FTT9EF/9zyZAgMBAAECgYAktngcYC35u7cQXDk+jMVyiVhWYU2ULxdSpPspgLGzrZyG1saOcTIi/XVX8Spd6+B6nmLQeF/FbU3rOeuD8U2clzul2Z2YMbJ0FYay9oVZFfp5gTEFpFRTVfzqUaZQBIjJe/xHL9kQVqc5xHlE/LVA27/Kx3dbC35Y7B4EVBDYAQJBAOhsX8ZreWLKPhXiXHTyLmNKhOHJc+0tFH7Ktise/0rNspojU7o9prOatKpNylp9v6kux7migcMRdVUWWiVe+4ECQQC8PqsuEz7B0yqirQchRg1DbHjh64bw9Kj82EN1/NzOUd53tP9tg+SO97EzsibK1F7tOcuwqsa7n2aY48mQ+y0ZAkBndA2xcRcnvOOjtAz5VO8G7R12rse181HjGfG6AeMadbKg30aeaGCyIxN1loiSfNR5xsPJwibGIBg81mUrqzqBAkB+K6rkaPXJR9XtzvdWb/N3235yPkDlw7Z4MiOVM3RzvR/VMDV7m8lXoeDde2zQyeMOMYy6ztwA6WgE1bhGOnQRAkEAouUBv1sVdSBlsexX15qphOmAevzYrpufKgJIRLFWQxroXMS7FTesj+f+FmGrpPCxIde1dqJ8lqYLTyJmbzMPYw==','MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIgHnOn7LLILlKETd6BFRJ0GqgS2Y3mn1wMQmyh9zEyWlz5p1zrahRahbXAfCfSqshSNfqOmAQzSHRVjCqjsAw1jyqrXaPdKBmr90DIpIxmIyKXv4GGAkPyJ/6FTFY99uhpiq0qadD/uSzQsefWo0aTvP/65zi3eof7TcZ32oWpwIDAQAB',NULL,NULL,'http://pay.egzosn.com/payBack1.json','http://pay.egzosn.com/payBack1.json','RSA','2088102169916436',NULL,NULL,'UTF-8',1) -- 这里支付证书加载方式,需要配合定制化的代码 详情pay-spring-boot-starter-demo\src\main\java\com\egzosn\pay\spring\boot\demo\config\MyAliPaymentPlatform.java ('11','aliPay','2016080400165436','2088102169916436','CLASS_PATH','MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCw7MD2Cwv/jnXssFjXnGx3JlGF57gJa2aYbJRV8MnNiPVpX4Ha+8ZjnQDhvkrWH4hHmzcujOr213HqloMpUSYBzCPiXGVRUUvdimejcHHTod7nI4g6nztzzfey/TXNDHmp7vY3pOIcjB0Zn0pkNAz2tKAFkqb4raHOqTB0QA0zD24Cn+26J2UJyYRcgeH0GtSQuUrm7yaGsuKakh+qtgWF6R71n5PMGOTQ5LH3i0WVHfCBkNGgJC6yC96HR4D7cosoyKD0+lp8UB/NVUWl7Tt/KLOgFUwh0GKSYFfv56O/VBV2+xqCGE4PlZESfVuOqz5vjjxzw3xDAUJrV8hSX/AJAgMBAAECggEBAKE0d3U4B4yo/2XUIH8EdgfykCFUSum6RFbpyBauORHfksyaSzV+ZvtomN8XhhSn0oJ8OMFfgM+86nz2+zdwSxMkMCYWTfLUAi4v59KRqAVO3kz4oS3Y3FDeAK3D7XuRvGFL7GgzAhtEx1cLPrsiehVn6s5pG15GxsIIgq/JlL1J88wn1zENLrVHmD6z/JpXvfb/RS1yR+5lyoohp4g0Ph9jJ3bCyUbRpK0QkPEzgAuWL0K2ITCL7PYHNAplI8d2xHHOLF9Qdjyx+ZrQ/RxtqzfyWzhqjsmp2qlgNCxWlt3woS9UhDB+nRvjEoWTJmIOszAMYuj8wGlX+3Ui3ALOdQECgYEA25EqnFPFinUnzgNvB6NYmh5STmZun6s4bUOLqwefKtEvrOtRwTu7sB7NIf37fizG3/MJUWHxiLy2/3ub4d2JxdDNBtJoEqnp6QB12qglCNa4CajdjtJa1dR81F9QvytsqEkmPYXFPPyviB0FcSIDAGMb3IbwvIfzBPY9WY8dJnECgYEAzkg3yKEFBZ8BU0WQ+3hyfKUoAhBEnxouxRSTBcXxwstJRiqaGTVe5aoJGQI+0xS7Z6q07XDtN2t97s6DnRLWbljsX6B64itzNhXRyzjdD3iZDU/KSw7khjhXf8XOZaj9eXmACDiUnkEn1xsM8bLiRGqB8y5f3aMY/RpuACGXnxkCgYEAx/zwT9Vpr1RIfjfYcJ+Su0X0994K0roUukj0tUJK8qf4gcsQ+y1aJe/YLib1ZBaKyj7G9O5+HmqtUAUZld/AdoJZzOXmz2EeYhD+R7wxh1xz4rCBpW3qOKvDS3jJxmZaIOoHv6/RWFxb0WGFrGcrTrX3EaWDLmWxr4pNlP5qsbECgYATllntrBR8/ycyEAX/SuWcHlaZM5BAh0zvm8+GGdCmDYWMqxjs0duL9URd4o+ynWJaKqR5c2KjA4r2tRdcP+Cqo7j2L5fbiAKtnQ7JvEGJaYsm72+nBuf+MrVkRZUepBhFg5r7rNu31zoAO+pTvQetNWvXeozRz93ckrjlPEtYaQKBgQDFwbV92rlRMLjZzlY+o0knoeJBjPQmPdiBTpGNimdy9L4c2Ure7affjcUiYhkKqrK5k5SScJTATgyQ7JF346FdtUtZ/6Kkj1RwJmmprPrDa9CATLoTle7g9OVd4sHT2ITHZMzPaF3ILvzcwJ70AD1xcxCQb+/7sDPmw7Mc8gOA7Q==','ali/alipayCertPublicKey_RSA2.crt','ali/appCertPublicKey_2016080400165436.crt,ali/alipayRootCert.crt',NULL,'http://pay.egzosn.com/payBack1.json','http://pay.egzosn.com/payBack1.json','RSA2','2088102169916436',NULL,NULL,'UTF-8',1) ,('2','unionPay',NULL,'700000000000001','PATH','D:/certs/acp_test_sign.pfx','D:/certs/acp_test_middle.cer','D:/certs/acp_test_root.cer','000000','http://pay.egzosn.com/payBack3.json','http://pay.egzosn.com/payBack3.json','RSA2',NULL,NULL,NULL,'UTF-8',1) ,( '3','wxPay','公众账号ID','合作者id(商户号)','URL','密钥','转账公钥,转账时必填','http://www.egzosn.com/certs/apiclient_cert.p12','默认为商户号','http://www.pay.egzosn.com/payBack3.json','http://www.pay.egzosn.com/payBack3.json','MD5',NULL,NULL,NULL,'UTF-8','1') ,( '4','wxV3Pay','公众账号ID','合作者id(商户号)','URL','密钥','转账公钥,转账时必填','http://www.egzosn.com/certs/apiclient_cert.p12','默认为商户号','http://www.pay.egzosn.com/payBack3.json','http://www.pay.egzosn.com/payBack3.json','MD5',NULL,NULL,NULL,'UTF-8','1') ,( '5','wxV3ProfitSharing','公众账号ID','合作者id(商户号)','URL','V3密钥','转账公钥,转账时必填','http://www.egzosn.com/certs/apiclient_cert.p12','默认为商户号','http://www.pay.egzosn.com/payBack3.json','http://www.pay.egzosn.com/payBack3.json','MD5',NULL,NULL,NULL,'UTF-8','1') ,( '6','wxV3ProfitSharing','公众账号ID','合作者id(商户号)','URL','V3密钥','转账公钥,转账时必填','http://www.egzosn.com/certs/apiclient_cert.p12','默认为商户号','http://www.pay.egzosn.com/payBack3.json','http://www.pay.egzosn.com/payBack3.json','MD5',NULL,NULL,NULL,'UTF-8','1') ,( '7','wxV3CombinePay','公众账号ID','合作者id(商户号)','URL','V3密钥','转账公钥,转账时必填','http://www.egzosn.com/certs/apiclient_cert.p12','默认为商户号','http://www.pay.egzosn.com/payBack3.json','http://www.pay.egzosn.com/payBack3.json','MD5',NULL,NULL,NULL,'UTF-8','1') ; ================================================ FILE: pay-spring-boot/pom.xml ================================================ com.egzosn pay-spring-boot-starter-parent 1.0.5 4.0.0 com.egzosn pay-spring-boot pay-spring-boot ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/MerchantPayServiceManager.java ================================================ package com.egzosn.pay.spring.boot.core; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import javax.imageio.ImageIO; import org.springframework.beans.factory.annotation.Autowired; import com.egzosn.pay.common.api.DefaultPayMessageHandler; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.api.TransferService; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.DefaultNoticeRequest; import com.egzosn.pay.common.bean.MethodType; import com.egzosn.pay.common.bean.NoticeParams; import com.egzosn.pay.common.bean.NoticeRequest; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.common.bean.RefundOrder; import com.egzosn.pay.common.bean.RefundResult; import com.egzosn.pay.common.bean.TransferOrder; import com.egzosn.pay.spring.boot.core.bean.MerchantPayOrder; import com.egzosn.pay.spring.boot.core.bean.MerchantQueryOrder; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; /** * 商户支付服务 * * @author egan *
 * email egzosn@gmail.com
 *
 * date 2019/5/8 19:43.
 * 
*/ public class MerchantPayServiceManager implements PayServiceManager { @Autowired private MerchantDetailsService detailsService; /** * 回调校验 * * @param detailsId 商户列表id * @param params 回调回来的参数集 * @return 签名校验 true通过 */ @Override public boolean verify(String detailsId, Map params) { return this.verify(detailsId, new NoticeParams(params)); } /** * 回调校验 * * @param detailsId 商户列表id * @param params 回调回来的参数集 * @return 签名校验 true通过 */ @Override public boolean verify(String detailsId, NoticeParams params) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().verify(params); } /** * 将请求参数或者请求流转化为 Map * * @param detailsId 商户列表id * @param parameterMap 请求参数 * @param is 请求流 * @return 获得回调的请求参数 * @see #getNoticeParams(String, NoticeRequest) */ @Deprecated @Override public Map getParameter2Map(String detailsId, Map parameterMap, InputStream is) { return getNoticeParams(detailsId, new DefaultNoticeRequest(parameterMap, is)).getBody(); } /** * 将请求参数或者请求流转化为 Map * * @param detailsId 商户列表id * @param request 通知请求 * @return 获得回调的请求参数 */ @Override public NoticeParams getNoticeParams(String detailsId, NoticeRequest request) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().getNoticeParams(request); } /** * 跳到支付页面 * 针对实时支付,即时付款 * * @param payOrder 商户支付订单信息 * @return 跳到支付页面 */ @Override public String toPay(MerchantPayOrder payOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); PayService payService = details.getPayService(); Map orderInfo = payService.orderInfo(payOrder); return payService.buildRequest(orderInfo, MethodType.POST); } /** * 获取支付预订单信息 * * @param payOrder 商户支付订单信息 * @return 支付预订单信息 */ @Override public Map app(MerchantPayOrder payOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); PayService payService = details.getPayService(); return payService.app(payOrder); } /** * 获取支付预订单信息 * * @param payOrder 商户支付订单信息 * @return 支付预订单信息 */ @Override public Map getOrderInfo(MerchantPayOrder payOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); PayService payService = details.getPayService(); return payService.orderInfo(payOrder); } /** * 刷卡付,pos主动扫码付款(条码付) * 刷脸付 * * @param payOrder 商户支付订单信息 * @return 支付结果 */ @Override public Map microPay(MerchantPayOrder payOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); //支付结果 return details.getPayService().microPay(payOrder); } /** * 获取二维码图像 * 二维码支付 * * @param payOrder 商户支付订单信息 * @return 二维码图像 * @throws IOException IOException */ @Override public byte[] toQrPay(MerchantPayOrder payOrder) throws IOException { //获取对应的支付账户操作工具(可根据账户id) PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(details.getPayService().genQrPay(payOrder), "JPEG", baos); return baos.toByteArray(); } /** * 获取二维码信息 * 二维码支付 * * @param payOrder 商户支付订单信息 * @return 二维码信息 */ @Override public String getQrPay(MerchantPayOrder payOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(payOrder.getDetailsId()); payOrder.setTransactionType(details.getPaymentPlatform().getTransactionType(payOrder.getWayTrade())); return details.getPayService().getQrPay(payOrder); } /** * 支付回调地址 * 方式二 * * @param detailsId 商户列表id * @param parameterMap 请求参数 * @param is 请求流 * @return 支付是否成功 * @throws IOException IOException * 拦截器相关增加, 详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} *

* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} * 方法过时,替代方法{@link #payBack(String, NoticeRequest)} */ @Deprecated @Override public String payBack(String detailsId, Map parameterMap, InputStream is) throws IOException { return this.payBack(detailsId, new DefaultNoticeRequest(parameterMap, is)); } /** * 支付回调地址 * 方式二 * * @param detailsId 商户列表id * @param request 请求参数 * @return 支付是否成功 * 拦截器相关增加, 详情查看{@link PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link PayService#setPayMessageHandler(PayMessageHandler)} *

* 如果未设置 {@link PayMessageHandler} 那么会使用默认的 {@link DefaultPayMessageHandler} */ @Override public String payBack(String detailsId, NoticeRequest request) { //业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler() PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); PayService payService = details.getPayService(); return payService.payBack(request).toMessage(); } /** * 查询 * * @param order 订单的请求体 * @return 返回查询回来的结果集,支付方原值返回 */ @Override public Map query(MerchantQueryOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(order.getDetailsId()); order.setTransactionType(details.getPaymentPlatform().getTransactionType(order.getWayTrade())); return details.getPayService().query(order); } /** * 交易关闭接口 * * @param order 订单的请求体 * @return 返回支付方交易关闭后的结果 */ @Override public Map close(MerchantQueryOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(order.getDetailsId()); order.setTransactionType(details.getPaymentPlatform().getTransactionType(order.getWayTrade())); return details.getPayService().close(order); } /** * 申请退款接口 * * @param detailsId 列表id * @param order 订单的请求体 * @return 返回支付方申请退款后的结果 */ @Override public RefundResult refund(String detailsId, RefundOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().refund(order); } /** * 查询退款 * * @param detailsId 列表id * @param order 订单的请求体 * @return 返回支付方查询退款后的结果 */ @Override public Map refundQuery(String detailsId, RefundOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().refundquery(order); } /** * 下载对账单 * * @param order 订单的请求体 * @return 返回支付方下载对账单的结果 */ @Override public Map downloadBill(MerchantQueryOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(order.getDetailsId()); return details.getPayService().downloadBill(order.getBillDate(), order.getBillType()); } /** * 转账 * * @param detailsId 列表id * @param order 转账订单 * @return 对应的转账结果 */ @Override public Map transfer(String detailsId, TransferOrder order) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().transfer(order); } /** * 转账查询 * * @param detailsId 列表id * @param outNo 商户转账订单号 * @param tradeNo 支付平台转账订单号 * @return 对应的转账订单 */ @Override public Map transferQuery(String detailsId, String outNo, String tradeNo) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().transferQuery(outNo, tradeNo); } /** * 转账查询 * * @param detailsId 列表id * @param assistOrder 辅助交易订单 * @return 对应的转账订单 */ @Override public Map transferQuery(String detailsId, AssistOrder assistOrder) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); PayService payService = details.getPayService(); if (payService instanceof TransferService) { return ((TransferService) payService).transferQuery(assistOrder); } //todo: 暂时兼容旧版本 return details.getPayService().transferQuery(assistOrder.getOutTradeNo(), assistOrder.getTradeNo()); } /** * 创建消息 * * @param detailsId 列表id * @param message 支付平台返回的消息 * @return 支付消息对象 */ @Override public PayMessage createMessage(String detailsId, Map message) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return details.getPayService().createMessage(message); } /** * 获取payService具体调用类引用 * * @param detailsId 列表id * @param payServiceClass payService类 * @return 具体调用类引用 */ @Override public T cast(String detailsId, Class payServiceClass) { PaymentPlatformMerchantDetails details = detailsService.loadMerchantByMerchantId(detailsId); return (T) details.getPayService(); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/PayBuilder.java ================================================ package com.egzosn.pay.spring.boot.core; /** * 用于构建对象的接口 * * @param 正在构建的对象的类型 * @author egan *
 *              email egzosn@gmail.com
 *
 *              date 2019/05/06 19:27.
 *         
*/ public interface PayBuilder { /** * 构建对象并返回它或null。 * * @return 如果实现允许,则要构建的对象或null。 */ O build(); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/PayConfigurerAdapter.java ================================================ package com.egzosn.pay.spring.boot.core; /** * 支付配置适配,主要用于外部调用者链式的方式创建对象 * @author egan *
 *              email egzosn@gmail.com
 *
 *              date 2019/5/6 19:43.
 *         
* @param 返回对应的服务构建器 */ public interface PayConfigurerAdapter { /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ B and(); /** * 获取构建器 * @return 构建器 */ B getBuilder(); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/PayServiceConfigurer.java ================================================ package com.egzosn.pay.spring.boot.core; import com.egzosn.pay.spring.boot.core.configurers.MerchantDetailsServiceConfigurer; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; /** * 支付服务配置,用于支付服务相关的配置,暂时主要为商户相关的配置,后期在进行添加别的配置 * @author egan *
 *              email egzosn@gmail.com
 *
 *              date 2019/5/8 19:06.
 *         
*/ public interface PayServiceConfigurer { /** * 商户配置 * @param configurer 商户配置 */ void configure(MerchantDetailsServiceConfigurer configurer); /** * 商户配置 * @param configurer 支付消息配置 */ void configure(PayMessageConfigurer configurer) ; } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/PayServiceManager.java ================================================ package com.egzosn.pay.spring.boot.core; import java.io.IOException; import java.io.InputStream; import java.util.Map; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.NoticeParams; import com.egzosn.pay.common.bean.NoticeRequest; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.common.bean.RefundOrder; import com.egzosn.pay.common.bean.RefundResult; import com.egzosn.pay.common.bean.TransferOrder; import com.egzosn.pay.spring.boot.core.bean.MerchantPayOrder; import com.egzosn.pay.spring.boot.core.bean.MerchantQueryOrder; /** * 商户支付服务 * * @author egan *
 * email egzosn@gmail.com
 *
 * date 020/1/2 15:03
 * 
*/ public interface PayServiceManager { /** * 回调校验 * * @param detailsId 商户列表id * @param params 回调回来的参数集 * @return 签名校验 true通过 */ @Deprecated boolean verify(String detailsId, Map params); /** * 回调校验 * * @param detailsId 商户列表id * @param params 回调回来的参数集 * @return 签名校验 true通过 */ boolean verify(String detailsId, NoticeParams params); /** * 将请求参数或者请求流转化为 Map * * @param detailsId 商户列表id * @param parameterMap 请求参数 * @param is 请求流 * @return 获得回调的请求参数 * @see #getNoticeParams(String, NoticeRequest) */ @Deprecated Map getParameter2Map(String detailsId, Map parameterMap, InputStream is); /** * 将请求参数或者请求流转化为 Map * * @param detailsId 商户列表id * @param request 通知请求 * @return 获得回调的请求参数 */ NoticeParams getNoticeParams(String detailsId, NoticeRequest request); /** * 跳到支付页面 * 针对实时支付,即时付款 * * @param payOrder 商户支付订单信息 * @return 跳到支付页面 */ String toPay(MerchantPayOrder payOrder); /** * 获取支付预订单信息 * * @param payOrder 商户支付订单信息 * @return 支付预订单信息 */ Map app(MerchantPayOrder payOrder); /** * 获取支付预订单信息 * * @param payOrder 商户支付订单信息 * @return 支付预订单信息 */ Map getOrderInfo(MerchantPayOrder payOrder); /** * 刷卡付,pos主动扫码付款(条码付) * 刷脸付 * * @param payOrder 商户支付订单信息 * @return 支付结果 */ Map microPay(MerchantPayOrder payOrder); /** * 获取二维码图像 * 二维码支付 * * @param payOrder 商户支付订单信息 * @return 二维码图像 * @throws IOException IOException */ byte[] toQrPay(MerchantPayOrder payOrder) throws IOException; /** * 获取二维码信息 * 二维码支付 * * @param payOrder 商户支付订单信息 * @return 二维码信息 */ String getQrPay(MerchantPayOrder payOrder); /** * 支付回调地址 * 方式二 * * @param detailsId 商户列表id * @param parameterMap 请求参数 * @param is 请求流 * @return 支付是否成功 * @throws IOException IOException * 拦截器相关增加, 详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} *

* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} */ @Deprecated String payBack(String detailsId, Map parameterMap, InputStream is) throws IOException; /** * 支付回调地址 * 方式二 * * @param detailsId 商户列表id * @param request 请求参数 * @return 支付是否成功 * 拦截器相关增加, 详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} *

* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} */ String payBack(String detailsId, NoticeRequest request); /** * 查询 * * @param order 订单的请求体 * @return 返回查询回来的结果集,支付方原值返回 */ Map query(MerchantQueryOrder order); /** * 交易关闭接口 * * @param order 订单的请求体 * @return 返回支付方交易关闭后的结果 */ Map close(MerchantQueryOrder order); /** * 申请退款接口 * * @param detailsId 列表id * @param order 订单的请求体 * @return 返回支付方申请退款后的结果 */ RefundResult refund(String detailsId, RefundOrder order); /** * 查询退款 * * @param detailsId 列表id * @param order 订单的请求体 * @return 返回支付方查询退款后的结果 */ Map refundQuery(String detailsId, RefundOrder order); /** * 下载对账单 * * @param order 订单的请求体 * @return 返回支付方下载对账单的结果 */ Map downloadBill(MerchantQueryOrder order); /** * 转账 * * @param detailsId 列表id * @param order 转账订单 * @return 对应的转账结果 */ Map transfer(String detailsId, TransferOrder order); /** * 转账查询 * * @param detailsId 列表id * @param outNo 商户转账订单号 * @param tradeNo 支付平台转账订单号 * @return 对应的转账订单 * @deprecated {@link #transferQuery(String, AssistOrder)} */ @Deprecated Map transferQuery(String detailsId, String outNo, String tradeNo); /** * 转账查询 * * @param detailsId 列表id * @param assistOrder 辅助交易订单 * @return 对应的转账订单 */ Map transferQuery(String detailsId, AssistOrder assistOrder); /** * 创建消息 * * @param detailsId 列表id * @param message 支付平台返回的消息 * @return 支付消息对象 */ PayMessage createMessage(String detailsId, Map message); /** * 获取payService具体调用类引用 * * @param detailsId 列表id * @param payServiceClass payService类 * @param 支付服务类引用 * @return 具体调用类引用 */ T cast(String detailsId, Class payServiceClass); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/bean/MerchantPayOrder.java ================================================ package com.egzosn.pay.spring.boot.core.bean; import com.egzosn.pay.common.bean.PayOrder; import com.egzosn.pay.common.bean.TransactionType; import java.math.BigDecimal; /** * 商户支付订单 * @author egan *
 *                 email egzosn@gmail.com
 *
 *                 date 2019/5/9 19:43.
 *                 
*/ public class MerchantPayOrder extends PayOrder { /** * 列表id */ private String detailsId; /** * 交易类型,交易方式, * 本字段与{@link com.egzosn.pay.common.bean.PayOrder#getTransactionType()}相同。 * * 例如,网页支付,扫码付等等 */ private String wayTrade; public MerchantPayOrder() { } public MerchantPayOrder(String detailsId, String wayTrade) { this.detailsId = detailsId; this.wayTrade = wayTrade; } public MerchantPayOrder(String detailsId, String wayTrade, String subject, String body, BigDecimal price, String outTradeNo) { super(subject, body, price, outTradeNo); this.detailsId = detailsId; this.wayTrade = wayTrade; } public String getDetailsId() { return detailsId; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } public String getWayTrade() { return wayTrade; } public void setWayTrade(String wayTrade) { this.wayTrade = wayTrade; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/bean/MerchantQueryOrder.java ================================================ package com.egzosn.pay.spring.boot.core.bean; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.BillType; import java.math.BigDecimal; import java.util.Date; /** * 订单辅助接口 * * @author egan * email egzosn@gmail.com * date 2017/3/12 14:50 */ public class MerchantQueryOrder extends AssistOrder { /** * 列表id */ private String detailsId; /** * 退款金额 */ private BigDecimal refundAmount; /** * 总金额 */ private BigDecimal totalAmount; /** * 账单时间:具体请查看对应支付平台 */ private Date billDate; /** * 账单类型:具体请查看对应支付平台 * 详情实现查看各个平台组件对应实现类 */ private BillType billType; /** * 支付平台订单号或者账单日期 */ private Object tradeNoOrBillDate; /** * 商户单号或者 账单类型 */ private String outTradeNoBillType; /** * 交易类型,交易方式, * 本字段与{@link com.egzosn.pay.common.bean.PayOrder#getTransactionType}相同。 *

* 例如,网页支付,扫码付等等 */ private String wayTrade; public String getDetailsId() { return detailsId; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } public BigDecimal getRefundAmount() { return refundAmount; } public void setRefundAmount(BigDecimal refundAmount) { this.refundAmount = refundAmount; } public BigDecimal getTotalAmount() { return totalAmount; } public void setTotalAmount(BigDecimal totalAmount) { this.totalAmount = totalAmount; } public Date getBillDate() { return billDate; } public void setBillDate(Date billDate) { this.billDate = billDate; } public BillType getBillType() { return billType; } public void setBillType(BillType billType) { this.billType = billType; } public Object getTradeNoOrBillDate() { return tradeNoOrBillDate; } public void setTradeNoOrBillDate(Object tradeNoOrBillDate) { this.tradeNoOrBillDate = tradeNoOrBillDate; } public String getOutTradeNoBillType() { return outTradeNoBillType; } public void setOutTradeNoBillType(String outTradeNoBillType) { this.outTradeNoBillType = outTradeNoBillType; } public String getWayTrade() { return wayTrade; } public void setWayTrade(String wayTrade) { this.wayTrade = wayTrade; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/builders/InMemoryMerchantDetailsServiceBuilder.java ================================================ package com.egzosn.pay.spring.boot.core.builders; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.bean.*; import com.egzosn.pay.spring.boot.core.provider.InMemoryMerchantDetailsManager; import java.util.ArrayList; import java.util.List; /** * 内存型商户列表服务构建器 * @author egan *

 *         email egzosn@gmail.com
 *         date  2019/5/6 19:36.
 *         
*/ public class InMemoryMerchantDetailsServiceBuilder extends MerchantDetailsServiceBuilder { private List merchantDetails = new ArrayList(); public void addMerchantDetails(PaymentPlatformMerchantDetails merchantDetail) { this.merchantDetails.add(merchantDetail); } public AliMerchantDetails ali(){ AliMerchantDetails details = new AliMerchantDetails(this); addMerchantDetails(details); return details; } public FuiouMerchantDetails fuiou(){ FuiouMerchantDetails details = new FuiouMerchantDetails(this); addMerchantDetails(details); return details; } public PayoneerMerchantDetails payoneer(){ PayoneerMerchantDetails details = new PayoneerMerchantDetails(this); addMerchantDetails(details); return details; } public PaypalMerchantDetails payPal(){ PaypalMerchantDetails details = new PaypalMerchantDetails(this); addMerchantDetails(details); return details; } public UnionMerchantDetails union(){ UnionMerchantDetails details = new UnionMerchantDetails(this); addMerchantDetails(details); return details; } public WxMerchantDetails wx(){ WxMerchantDetails details = new WxMerchantDetails(this); addMerchantDetails(details); return details; } public WxV3MerchantDetails wxV3(){ WxV3MerchantDetails details = new WxV3MerchantDetails(this); addMerchantDetails(details); return details; } /** * 开始构建 * * @return 商户列表服务 */ @Override protected MerchantDetailsService performBuild() { InMemoryMerchantDetailsManager merchantDetailsManager = new InMemoryMerchantDetailsManager(); merchantDetailsManager.setPayMessageConfigurer(configurer); merchantDetailsManager.createMerchant(merchantDetails); return merchantDetailsManager; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/builders/JdbcMerchantDetailsServiceBuilder.java ================================================ package com.egzosn.pay.spring.boot.core.builders; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; import com.egzosn.pay.spring.boot.core.provider.CacheMerchantDetailsManager; import com.egzosn.pay.spring.boot.core.provider.JdbcMerchantDetailsManager; import com.egzosn.pay.spring.boot.core.provider.MerchantDetailsManager; /** * 内存型商户列表服务构建器 * * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/5/6 19:36.
 *         
*/ public class JdbcMerchantDetailsServiceBuilder extends MerchantDetailsServiceBuilder { private JdbcTemplate jdbcTemplate; private boolean cache = false; public JdbcMerchantDetailsServiceBuilder(DataSource source) { setJdbcTemplate(new JdbcTemplate(source)); } public JdbcMerchantDetailsServiceBuilder(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public JdbcMerchantDetailsServiceBuilder(boolean cache) { this.cache = cache; } public JdbcMerchantDetailsServiceBuilder() { } /** * 设置缓存 * * @param cache 缓存 * @return 当前 */ public JdbcMerchantDetailsServiceBuilder cache(boolean cache) { setCache(cache); return this; } /** * 设置jdbc 模版 * * @param jdbcTemplate jdbcTemplate * @return 当前 */ public JdbcMerchantDetailsServiceBuilder template(JdbcTemplate jdbcTemplate) { setJdbcTemplate(jdbcTemplate); return this; } /** * 设置数据源 * * @param source 数据源 * @return 当前 */ public JdbcMerchantDetailsServiceBuilder dataSource(DataSource source) { setJdbcTemplate(new JdbcTemplate(source)); return this; } public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } private void setJdbcTemplate(JdbcTemplate jdbcTemplate) { if (null != this.jdbcTemplate) { return; } this.jdbcTemplate = jdbcTemplate; } public boolean isCache() { return cache; } public void setCache(boolean cache) { this.cache = cache; } /** * 开始构建 * * @return 商户列表服务· */ @Override protected MerchantDetailsService performBuild() { MerchantDetailsManager manager = new JdbcMerchantDetailsManager(jdbcTemplate); if (cache) { manager = new CacheMerchantDetailsManager(manager); } manager.setPayMessageConfigurer(configurer); return manager; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/builders/MerchantDetailsServiceBuilder.java ================================================ package com.egzosn.pay.spring.boot.core.builders; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import com.egzosn.pay.spring.boot.core.PayBuilder; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; /** * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/5/6 19:36.
 *         
*/ public class MerchantDetailsServiceBuilder implements PayBuilder { protected PayMessageConfigurer configurer; public static InMemoryMerchantDetailsServiceBuilder inMemory() { return new InMemoryMerchantDetailsServiceBuilder(); } public static JdbcMerchantDetailsServiceBuilder jdbc() { return new JdbcMerchantDetailsServiceBuilder(); } public static JdbcMerchantDetailsServiceBuilder jdbc(boolean cache) { return new JdbcMerchantDetailsServiceBuilder(); } public static JdbcMerchantDetailsServiceBuilder jdbc(DataSource source) { return new JdbcMerchantDetailsServiceBuilder(source); } public static JdbcMerchantDetailsServiceBuilder jdbc(JdbcTemplate jdbcTemplate) { return new JdbcMerchantDetailsServiceBuilder(jdbcTemplate); } /** * 构建对象并返回它或null。 * * @return 如果实现允许,则要构建的对象或null。 */ @Override public MerchantDetailsService build() { return performBuild(); } /** * 开始构建 * * @return 商户列表服务 */ protected MerchantDetailsService performBuild() { throw new UnsupportedOperationException("无法构建商家服务(需要使用inMemory()或jdbc())"); } public void setConfigurer(PayMessageConfigurer configurer) { this.configurer = configurer; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/configurers/DefalutPayMessageConfigurer.java ================================================ package com.egzosn.pay.spring.boot.core.configurers; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; /** * 支付回调配置中心 * @author egan *
 *         email egzosn@gmail.com
 *         date 2019/9/7.22:08
 *
*/ public class DefalutPayMessageConfigurer implements PayMessageConfigurer { /** * 消息处理器集 * * key 为商户平台 * value 为对应得处理器 */ private Map> handlers = new HashMap>(); /** * 消息拦截器集 * * key 为商户平台 * value 为对应得拦截器 */ private Map>> interceptors = new HashMap>>(); /** * 添加处理器 * * @param platform 商户平台,渠道 * @param handler 处理器 */ @Override public void addHandler(PaymentPlatform platform, PayMessageHandler handler) { if (handlers.containsKey(platform)){ throw new IllegalArgumentException(platform.getPlatform() + "已存在,请勿重复设置"); } this.handlers.put(platform, handler); } /** * 获取处理器 * * @param platform 商户平台,渠道 * @return 处理器 */ @Override public PayMessageHandler getHandler(PaymentPlatform platform) { return handlers.get(platform); } /** * 添加拦截器 * * @param platform 商户平台,渠道 * @param interceptor 拦截器 */ @Override public void addInterceptor(PaymentPlatform platform, PayMessageInterceptor interceptor) { List> interceptors = this.interceptors.get(platform); if (null == interceptors){ interceptors = new ArrayList<>(); this.interceptors.put(platform, interceptors); } interceptors.add(interceptor); } /** * 获取拦截器 * * @param platform 商户平台,渠道 * @return 拦截器 */ @Override public List> getInterceptor(PaymentPlatform platform) { return interceptors.get(platform); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/configurers/MerchantDetailsServiceConfigurer.java ================================================ package com.egzosn.pay.spring.boot.core.configurers; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.builders.JdbcMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.builders.MerchantDetailsServiceBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; /** * 商户列表服务配置 * * @author egan *
 *      email egzosn@gmail.com
 *
 *      date 2019/5/8 19:54.
 * 
*/ public class MerchantDetailsServiceConfigurer implements PayConfigurerAdapter { private MerchantDetailsServiceBuilder builder; @Autowired private PayMessageConfigurer configurer; public void setBuilder(MerchantDetailsServiceBuilder builder) { this.builder = builder; } public InMemoryMerchantDetailsServiceBuilder inMemory() { InMemoryMerchantDetailsServiceBuilder builder = MerchantDetailsServiceBuilder.inMemory(); initBuilder(builder); return builder; } public MerchantDetailsServiceBuilder initBuilder(MerchantDetailsServiceBuilder builder) { builder.setConfigurer(this.configurer); setBuilder(builder); return builder; } public JdbcMerchantDetailsServiceBuilder jdbc() { JdbcMerchantDetailsServiceBuilder builder = MerchantDetailsServiceBuilder.jdbc(); initBuilder(builder); return builder; } public JdbcMerchantDetailsServiceBuilder jdbc(DataSource source) { JdbcMerchantDetailsServiceBuilder builder = MerchantDetailsServiceBuilder.jdbc(source); initBuilder(builder); return builder; } /** * * 将在未来可能进行移除,避免项目不用JdbcTemplate最为数据源操作并且不需要引入JdbcTemplate包时导致的不必要报错 * * 替代方式{@link #jdbc()}与{@link #jdbc(DataSource)}进行替代 * * jdbc().template(JdbcTemplate); * * @param jdbcTemplate jdbc模版 * @return jdbc商户列表服务构建器 */ @Deprecated public JdbcMerchantDetailsServiceBuilder jdbc(JdbcTemplate jdbcTemplate) { JdbcMerchantDetailsServiceBuilder builder = MerchantDetailsServiceBuilder.jdbc(jdbcTemplate); initBuilder(builder); return builder; } /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public MerchantDetailsServiceBuilder and() { return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public MerchantDetailsServiceBuilder getBuilder() { return builder; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/configurers/PayMessageConfigurer.java ================================================ package com.egzosn.pay.spring.boot.core.configurers; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import java.util.List; /** * @author egan *
 *         email egzosn@gmail.com
 *         date 2019/9/7.23:54
 * 
*/ public interface PayMessageConfigurer { /** * 添加处理器 * * @param platform 商户平台,渠道 * @param handler 处理器 */ void addHandler(PaymentPlatform platform, PayMessageHandler handler); /** * 获取处理器 * * @param platform 商户平台,渠道 * @return 处理器 */ PayMessageHandler getHandler(PaymentPlatform platform); /** * 添加拦截器 * * @param platform 商户平台,渠道 * @param interceptor 拦截器 */ void addInterceptor(PaymentPlatform platform, PayMessageInterceptor interceptor); /** * 获取拦截器 * * @param platform 商户平台,渠道 * @return 拦截器 */ List> getInterceptor(PaymentPlatform platform); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/MerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; import com.egzosn.pay.common.api.PayConfigStorage; import java.io.Serializable; /** * 商户信息列表 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date 2018/12/29 11:03.
 *                 
*/ public interface MerchantDetails extends PayConfigStorage, Serializable { /** * 获取支付商户详细信息id * * @return 支付商户详细信息id */ String getDetailsId(); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/MerchantDetailsService.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; /** * 提供给客户端获取商户列表信息的服务 * * @author egan *
 *         email egzosn@gmail.com
 *         date 2018-12-29 10:53:08
 *         
*/ public interface MerchantDetailsService { /** * 通过支付商户id加载对应的商户信息列表 * @param merchantId 支付商户id * @return 商户信息列表 */ T loadMerchantByMerchantId(String merchantId); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/MerchantNotFoundException.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; /** * 商户不存在异常 * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/4/6 16:43.
 *         
*/ public class MerchantNotFoundException extends RuntimeException { /** * 商户列表id */ private String detailsId; private static final String MESSAGE = "不存在的商户列表id:"; /** * * @param detailsId 商户列表id */ public MerchantNotFoundException(String detailsId) { this(MESSAGE + detailsId, null); } /** * @param detailsId 商户列表id * @param cause 异常 */ public MerchantNotFoundException(String detailsId, Throwable cause) { super(MESSAGE + detailsId, cause); this.detailsId = detailsId; } /** * 获取商户id * @return 商户id */ public String getMerchantId(){ return detailsId; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/PaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.BasePayType; import com.egzosn.pay.common.http.HttpConfigStorage; /** * 支付平台 * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/4/6 17:20.
 *         
*/ public interface PaymentPlatform extends BasePayType { /** * 获取商户平台 * @return 商户平台 */ String getPlatform(); /** * 获取支付平台对应的支付服务 * @param payConfigStorage 支付配置 * @return 支付服务 */ S getPayService(PayConfigStorage payConfigStorage); /** * 获取支付平台对应的支付服务 * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ S getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/PaymentPlatformMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; import com.egzosn.pay.common.api.PayService; /** * 支付平台商户列表 * @author egan *
 *         email egzosn@gmail.com
 *         date 2019/4/6 17:28.
 *         
*/ public interface PaymentPlatformMerchantDetails extends MerchantDetails{ /** * 获取支付平台对应的支付服务 * @return 支付服务 */ S getPayService(); /** * 获取支付平台 * @return 支付平台 */ PaymentPlatform getPaymentPlatform(); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/PaymentPlatformServiceAdapter.java ================================================ package com.egzosn.pay.spring.boot.core.merchant; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; /** * 支付商户服务适配器 * @author egan *
 *                 email egzosn@gmail.com
 *
 *                 date 2019/5/9 19:28.
 *                 
*/ public interface PaymentPlatformServiceAdapter { /** * 初始化服务 * @return 支付商户服务适配器 */ PaymentPlatformServiceAdapter initService(); /** * 获取支付平台对应的支付服务 * @return 支付服务 */ S getPayService(); /** * 获取HTTP请求配置 * @return HTTP请求配置 */ HttpConfigStorage getHttpConfigStorage(); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/AliMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.ali.api.AliPayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; /** * 支付宝商户信息列表 * * @author egan *
 *                         email egzosn@gmail.com
 *                         date   2019/4/6 14:30.
 *                         
*/ public class AliMerchantDetails extends AliPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public AliMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public AliMerchantDetails() { init(); } public void init() { if (null != platform){ return; } String platformName = AliPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService) { payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public AliMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public AliMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public AliMerchantDetails notifyUrl(String notifyUrl) { setNotifyUrl(notifyUrl); return this; } public AliMerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } public AliMerchantDetails signType(String signType) { setSignType(signType); return this; } public AliMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public AliMerchantDetails test(boolean test) { setTest(test); return this; } public AliMerchantDetails pid(String pid) { setPid(pid); return this; } public AliMerchantDetails appid(String appid) { setAppid(appid); return this; } public AliMerchantDetails keyPrivate(String keyPrivate) { setKeyPrivate(keyPrivate); return this; } public AliMerchantDetails keyPublic(String keyPublic) { setKeyPublic(keyPublic); return this; } public AliMerchantDetails seller(String seller) { setSeller(seller); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/CommonPaymentPlatformMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.BasePayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.MerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import java.io.IOException; import java.io.InputStream; /** * 公共的支付商户信息列表 * * @author egan *
 * email egzosn@gmail.com
 * date   2019/4/9 19:39.
 * 
*/ public class CommonPaymentPlatformMerchantDetails extends BasePayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; private String appId; private String mchId; private String seller; private String subAppId; private String subMchId; /** * 证书(PKCS12) */ private Object keystore; /** * 公钥证书 */ private Object keyPublicCert; /** * 证书,这里针对双证书校验, 银联的根级证书 */ private Object keyCert; /** * 应用私钥证书,rsa_private pkcs8格式 生成签名时使用 */ private String keyPrivateCertPwd; /** * 证书存储类型 */ private CertStoreType certStoreType; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private volatile PaymentPlatform platform; private MerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public MerchantDetailsServiceBuilder and() { return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public MerchantDetailsServiceBuilder getBuilder() { return builder; } public CommonPaymentPlatformMerchantDetails(MerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public CommonPaymentPlatformMerchantDetails() { } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { if (null == platform){ platform = PaymentPlatforms.getPaymentPlatform(getPayType()); } return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { getPaymentPlatform(); if (null == payService){ payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public void setHttpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public void setAppId(String appId) { this.appId = appId; } public String getMchId() { return mchId; } public void setMchId(String mchId) { this.mchId = mchId; } @Override @Deprecated public String getAppid() { return appId; } /** * 应用id * 纠正名称 * * @return 应用id */ @Override public String getAppId() { return appId; } @Override public String getPid() { return mchId; } @Override public String getSeller() { return seller; } public void setSeller(String seller) { this.seller = seller; } public String getSubAppId() { return subAppId; } public void setSubAppId(String subAppId) { this.subAppId = subAppId; } public String getSubMchId() { return subMchId; } public void setSubMchId(String subMchId) { this.subMchId = subMchId; } /** * 设置私钥证书 * * @param keystore 私钥证书地址 或者证书内容字符串 * 私钥证书密码 {@link #setKeyPrivateCertPwd(String)} */ public void setKeystore(String keystore) { super.setKeyPrivate(keystore); this.keystore = keystore; } /** * 设置私钥证书 * * @param keystore 私钥证书信息流 * 私钥证书密码 {@link #setKeyPrivateCertPwd(String)} */ public void setKeystore(InputStream keystore) { this.keystore = keystore; } public InputStream getKeystoreInputStream() throws IOException { return certStoreType.getInputStream(keystore); } public Object getKeystore() { return keystore; } public String getKeystorePwd() { return getKeyPrivateCertPwd(); } public void setKeystorePwd(String keystorePwd) { setKeyPrivateCertPwd(keystorePwd); } /** * 获取私钥证书密码 * @return 私钥证书密码 */ public String getKeyPrivateCertPwd() { return keyPrivateCertPwd; } public void setKeyPrivateCertPwd(String keyPrivateCertPwd) { this.keyPrivateCertPwd = keyPrivateCertPwd; } public String getKeyPublicCert() { return (String) keyPublicCert; } /** * 设置公钥证书 * * @param keyPublicCert 证书信息或者证书路径 */ public void setKeyPublicCert(String keyPublicCert) { setKeyPublic(keyPublicCert); this.keyPublicCert = keyPublicCert; } /** * 设置公钥证书 * * @param keyPublicCert 证书文件 */ public void setKeyPublicCert(InputStream keyPublicCert) { this.keyPublicCert = keyPublicCert; } public Object getKeyCert() { return keyCert; } /** * 公钥证书,这里针对双证书校验, 银联的根级证书 * * @param keyCert 证书信息或者证书路径 */ public void setKeyCert(String keyCert) { this.keyCert = keyCert; } /** * 公钥证书,这里针对双证书校验, 银联的根级证书 * * @param keyCert 证书文件 */ public void setKeyCert(InputStream keyCert) { this.keyCert = keyCert; } public InputStream getKeyPublicCertInputStream() throws IOException { return certStoreType.getInputStream(keyPublicCert); } public InputStream getKeyCertInputStream() throws IOException { return certStoreType.getInputStream(keyCert); } /** * 证书存储类型 * * @return 证书存储类型 */ public CertStoreType getCertStoreType() { return certStoreType; } public void setCertStoreType(CertStoreType certStoreType) { this.certStoreType = certStoreType; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/FuiouMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.fuiou.api.FuiouPayConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.FuiouPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; /** * 富友商户信息列表 * * @author egan *
 *                         email egzosn@gmail.com
 *                         date   2019/4/6 14:30.
 *                         
*/ public class FuiouMerchantDetails extends FuiouPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public FuiouMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public FuiouMerchantDetails() { init(); } public void init() { if (null != platform) { return; } String platformName = FuiouPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService) { payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public FuiouMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public FuiouMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public FuiouMerchantDetails notifyUrl(String notifyUrl) { setNotifyUrl(notifyUrl); return this; } public FuiouMerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } public FuiouMerchantDetails signType(String signType) { setSignType(signType); return this; } public FuiouMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public FuiouMerchantDetails test(boolean test) { setTest(test); return this; } public FuiouMerchantDetails mchntCd(String mchntCd) { setMchntCd(mchntCd); return this; } public FuiouMerchantDetails keyPrivate(String keyPrivate) { setKeyPrivate(keyPrivate); return this; } public FuiouMerchantDetails keyPublic(String keyPublic) { setKeyPublic(keyPublic); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/PayPalV2MerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.paypal.api.PayPalConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaypalV2PaymentPlatform; /** * 贝宝商户信息列表 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date   2019/4/6 14:30.
 *                 
*/ public class PayPalV2MerchantDetails extends PayPalConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public PayPalV2MerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public PayPalV2MerchantDetails() { init(); } public void init() { if (null != platform) { return; } String platformName = PaypalV2PaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService) { payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public PayPalV2MerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public PayPalV2MerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public PayPalV2MerchantDetails signType(String signType) { setSignType(signType); return this; } public PayPalV2MerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public PayPalV2MerchantDetails test(boolean test) { setTest(test); return this; } public PayPalV2MerchantDetails clientID(String clientID) { setClientID(clientID); return this; } public PayPalV2MerchantDetails clientSecret(String clientSecret) { setClientSecret(clientSecret); return this; } public PayPalV2MerchantDetails cancelUrl(String cancelUrl) { setNotifyUrl(cancelUrl); return this; } public PayPalV2MerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/PayoneerMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.payoneer.api.PayoneerConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PayoneerPaymentPlatform; /** * P卡(派安盈)商户信息列表 * * @author egan *
 *                         email egzosn@gmail.com
 *                         date   2019/4/6 14:30.
 *                         
*/ public class PayoneerMerchantDetails extends PayoneerConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform ; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public PayoneerMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public PayoneerMerchantDetails() { init(); } public void init() { if (null != platform){ return; } String platformName = PayoneerPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService){ payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public PayoneerMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public PayoneerMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public PayoneerMerchantDetails programId(String programId) { setProgramId(programId); return this; } public PayoneerMerchantDetails userName(String userName) { setUserName(userName); return this; } public PayoneerMerchantDetails apiPassword(String apiPassword) { setApiPassword(apiPassword); return this; } public PayoneerMerchantDetails signType(String signType) { setSignType(signType); return this; } public PayoneerMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public PayoneerMerchantDetails test(boolean test) { setTest(test); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/PaypalMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.paypal.api.PayPalConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaypalPaymentPlatform; /** * 贝宝商户信息列表 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date   2019/4/6 14:30.
 *                 
*/ public class PaypalMerchantDetails extends PayPalConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform ; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public PaypalMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public PaypalMerchantDetails() { init(); } public void init() { String platformName = PaypalPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService){ payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public PaypalMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public PaypalMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public PaypalMerchantDetails signType(String signType) { setSignType(signType); return this; } public PaypalMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public PaypalMerchantDetails test(boolean test) { setTest(test); return this; } public PaypalMerchantDetails clientID(String clientID) { setClientID(clientID); return this; } public PaypalMerchantDetails clientSecret(String clientSecret) { setClientSecret(clientSecret); return this; } public PaypalMerchantDetails cancelUrl(String cancelUrl) { setNotifyUrl(cancelUrl); return this; } public PaypalMerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/UnionMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import java.io.InputStream; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.UnionPaymentPlatform; import com.egzosn.pay.union.api.UnionPayConfigStorage; /** * 银联商户信息列表 * * @author egan *
 *                         email egzosn@gmail.com
 *                         date   2019/4/6 14:30.
 *                         
*/ public class UnionMerchantDetails extends UnionPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public UnionMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public UnionMerchantDetails() { init(); } public void init() { if (null != platform){ return; } String platformName = UnionPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService){ payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public UnionMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public UnionMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public UnionMerchantDetails notifyUrl(String notifyUrl) { setNotifyUrl(notifyUrl); return this; } public UnionMerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } public UnionMerchantDetails signType(String signType) { setSignType(signType); return this; } public UnionMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public UnionMerchantDetails test(boolean test) { setTest(test); return this; } public UnionMerchantDetails acpMiddleCert(String acpMiddleCert) { setAcpMiddleCert(acpMiddleCert); return this; } public UnionMerchantDetails acpMiddleCert(InputStream acpMiddleCert) { setAcpMiddleCert(acpMiddleCert); return this; } public UnionMerchantDetails acpRootCert(String acpRootCert) { setAcpRootCert(acpRootCert); return this; } public UnionMerchantDetails acpRootCert(InputStream acpRootCert) { setAcpRootCert(acpRootCert); return this; } public UnionMerchantDetails keyPrivateCert(String keyPrivateCert) { setKeyPrivateCert(keyPrivateCert); return this; } public UnionMerchantDetails keyPrivateCert(InputStream keyPrivateCert) { setKeyPrivateCert(keyPrivateCert); return this; } public UnionMerchantDetails keyPrivateCertPwd(String keyPrivateCertPwd) { setKeyPrivateCertPwd(keyPrivateCertPwd); return this; } public UnionMerchantDetails certStoreType(CertStoreType certStoreType) { setCertStoreType(certStoreType); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/WxMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxPaymentPlatform; import com.egzosn.pay.wx.api.WxPayConfigStorage; /** * 支付宝商户信息列表 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date   2019/4/6 20:10.
 *                 
*/ public class WxMerchantDetails extends WxPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public WxMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public WxMerchantDetails() { init(); } public void init() { if (null != platform) { return; } String platformName = WxPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService) { payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public WxMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public WxMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public WxMerchantDetails notifyUrl(String notifyUrl) { setNotifyUrl(notifyUrl); return this; } public WxMerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } public WxMerchantDetails signType(String signType) { setSignType(signType); return this; } public WxMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public WxMerchantDetails test(boolean test) { setTest(test); return this; } public WxMerchantDetails appid(String appid) { setAppid(appid); return this; } public WxMerchantDetails secretKey(String secretKey) { setSecretKey(secretKey); return this; } public WxMerchantDetails keyPublic(String keyPublic) { setKeyPublic(keyPublic); return this; } public WxMerchantDetails mchId(String mchId) { setMchId(mchId); return this; } public WxMerchantDetails subAppid(String subAppid) { setSubAppid(subAppid); return this; } public WxMerchantDetails subMchId(String subMchId) { setSubMchId(subMchId); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/WxV3MerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxV3PaymentPlatform; import com.egzosn.pay.wx.v3.api.WxPayConfigStorage; /** * 支付宝商户信息列表 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date   2019/4/6 20:10.
 *                 
*/ public class WxV3MerchantDetails extends WxPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public WxV3MerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public WxV3MerchantDetails() { init(); } public WxV3MerchantDetails init() { if (null != platform) { return this; } String platformName = WxV3PaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); return this; } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService) { payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { initService(); return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public WxV3MerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public void setDetailsId(String detailsId) { this.detailsId = detailsId; } public WxV3MerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public WxV3MerchantDetails notifyUrl(String notifyUrl) { setNotifyUrl(notifyUrl); return this; } public WxV3MerchantDetails returnUrl(String returnUrl) { setReturnUrl(returnUrl); return this; } public WxV3MerchantDetails signType(String signType) { setSignType(signType); return this; } public WxV3MerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } public WxV3MerchantDetails test(boolean test) { setTest(test); return this; } public WxV3MerchantDetails appId(String appId) { setAppId(appId); return this; } public WxV3MerchantDetails keyPrivate(String keyPrivate) { setKeyPrivate(keyPrivate); return this; } public WxV3MerchantDetails v3ApiKey(String v3ApiKey) { setV3ApiKey(v3ApiKey); return this; } public WxV3MerchantDetails apiKey(String apiKey) { setApiKey(apiKey); return this; } public WxV3MerchantDetails keyPublic(String keyPublic) { setKeyPublic(keyPublic); return this; } public WxV3MerchantDetails keyPublicId(String keyPublicId) { setKeyPublicId(keyPublicId); return this; } public WxV3MerchantDetails merchantSerialNumber(String merchantSerialNumber) { setMerchantSerialNumber(merchantSerialNumber); return this; } public WxV3MerchantDetails mchId(String mchId) { setMchId(mchId); return this; } public WxV3MerchantDetails subAppId(String subAppId) { setSubAppId(subAppId); return this; } public WxV3MerchantDetails subMchId(String subMchId) { setSubMchId(subMchId); return this; } public WxV3MerchantDetails apiClientKeyP12(Object apiClientKeyP12) { setApiClientKeyP12(apiClientKeyP12); return this; } public WxV3MerchantDetails certStoreType(CertStoreType certStoreType) { setCertStoreType(certStoreType); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/merchant/bean/WxYouDianMerchantDetails.java ================================================ package com.egzosn.pay.spring.boot.core.merchant.bean; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayConfigurerAdapter; import com.egzosn.pay.spring.boot.core.builders.InMemoryMerchantDetailsServiceBuilder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformServiceAdapter; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PayoneerPaymentPlatform; import com.egzosn.pay.wx.youdian.api.WxYouDianPayConfigStorage; /** * P卡(派安盈)商户信息列表 * * @author egan *
 *                         email egzosn@gmail.com
 *                         date   2019/4/6 14:30.
 *                         
*/ public class WxYouDianMerchantDetails extends WxYouDianPayConfigStorage implements PaymentPlatformMerchantDetails, PaymentPlatformServiceAdapter, PayConfigurerAdapter { private String detailsId; /** * 商户对应的支付服务 */ private volatile PayService payService; /** * 商户平台 */ private PaymentPlatform platform ; private InMemoryMerchantDetailsServiceBuilder builder; /** * HTTP请求配置 */ private HttpConfigStorage httpConfigStorage; /** * 外部调用者使用,链式的做法 * * @return 返回对应外部调用者 */ @Override public InMemoryMerchantDetailsServiceBuilder and() { initService(); return getBuilder(); } /** * 获取构建器 * * @return 构建器 */ @Override public InMemoryMerchantDetailsServiceBuilder getBuilder() { return builder; } public WxYouDianMerchantDetails(InMemoryMerchantDetailsServiceBuilder builder) { this(); this.builder = builder; } public WxYouDianMerchantDetails() { init(); } public void init() { String platformName = PayoneerPaymentPlatform.platformName; setPayType(platformName); platform = PaymentPlatforms.getPaymentPlatform(platformName); } /** * 获取支付平台 * * @return 支付平台 */ @Override public PaymentPlatform getPaymentPlatform() { return platform; } /** * 初始化服务 * * @return 支付商户服务适配器 */ @Override public PaymentPlatformServiceAdapter initService() { init(); if (null == payService){ payService = platform.getPayService(this, getHttpConfigStorage()); } return this; } /** * 获取支付平台对应的支付服务 * * @return 支付服务 */ @Override public PayService getPayService() { return payService; } /** * 获取HTTP请求配置 * * @return HTTP请求配置 */ @Override public HttpConfigStorage getHttpConfigStorage() { return httpConfigStorage; } public WxYouDianMerchantDetails httpConfigStorage(HttpConfigStorage httpConfigStorage) { this.httpConfigStorage = httpConfigStorage; return this; } /** * 获取支付商户id * * @return 支付商户id */ @Override public String getDetailsId() { return detailsId; } public WxYouDianMerchantDetails detailsId(String detailsId) { this.detailsId = detailsId; return this; } public WxYouDianMerchantDetails keyPrivate(String keyPrivate) { setKeyPrivate(keyPrivate); return this; } public WxYouDianMerchantDetails keyPublic(String keyPublic) { setKeyPublic(keyPublic); return this; } public WxYouDianMerchantDetails seller(String seller) { setSeller(seller); return this; } public WxYouDianMerchantDetails signType(String signType) { setSignType(signType); return this; } public WxYouDianMerchantDetails inputCharset(String inputCharset) { setInputCharset(inputCharset); return this; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/CacheMerchantDetailsManager.java ================================================ package com.egzosn.pay.spring.boot.core.provider; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.springframework.util.Assert; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantNotFoundException; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; /** * 缓存支付账户(商户)存储器 * * @author egan *
 * email egzosn@gmail.com
 * date 2021/1/7
 * 
*/ public class CacheMerchantDetailsManager implements MerchantDetailsManager { private Map merchantDetails = new HashMap(); private MerchantDetailsManager delegate; public CacheMerchantDetailsManager(MerchantDetailsManager delegate) { this.delegate = delegate; } /** * 创建商户 * * @param merchant 商户信息 */ @Override public void createMerchant(PaymentPlatformMerchantDetails merchant) { Assert.isTrue(!merchantExists(merchant.getDetailsId()), "商户信息已存在"); merchantDetails.put(merchant.getDetailsId(), merchant); delegate.createMerchant(merchant); } /** * 创建商户 * * @param merchants 商户信息 */ @Override public void createMerchant(Collection merchants) { for (PaymentPlatformMerchantDetails merchant : merchants) { this.createMerchant(merchant); } } /** * 更新商户 * * @param merchant 商户信息 */ @Override public void updateMerchant(PaymentPlatformMerchantDetails merchant) { Assert.isTrue(merchantExists(merchant.getDetailsId()), "商户信息不存在"); merchantDetails.put(merchant.getDetailsId(), merchant); delegate.updateMerchant(merchant); } /** * 删除商户 * * @param id 商户id */ @Override public void deleteMerchant(String id) { merchantDetails.remove(id); delegate.deleteMerchant(id); } /** * 检查商户是否存在 * * @param id 商户id * @return 检查商户是否存在 */ @Override public boolean merchantExists(String id) { boolean exist = merchantDetails.containsKey(id); if (exist) { return exist; } return delegate.merchantExists(id); } /** * 设置支付消息配置中心 * * @param configurer 配置 */ @Override public void setPayMessageConfigurer(PayMessageConfigurer configurer) { delegate.setPayMessageConfigurer(configurer); } /** * 通过支付商户id加载对应的商户信息列表 * * @param merchantId 支付商户id * @return 商户信息列表 */ @Override public PaymentPlatformMerchantDetails loadMerchantByMerchantId(String merchantId) { PaymentPlatformMerchantDetails details = merchantDetails.get(merchantId); if (null != details) { return details; } details = delegate.loadMerchantByMerchantId(merchantId); if (null == details){ throw new MerchantNotFoundException(merchantId); } merchantDetails.put(details.getDetailsId(), details); return details; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/InMemoryMerchantDetailsManager.java ================================================ package com.egzosn.pay.spring.boot.core.provider; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.PayMessage; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantNotFoundException; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import org.springframework.util.Assert; import java.util.*; /** * 内存型支付账户(商户)存储器 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date 2018-11-22 17:18:03
 *           
*/ public class InMemoryMerchantDetailsManager implements MerchantDetailsManager { private Map merchantDetails = new HashMap(); private PayMessageConfigurer configurer; public InMemoryMerchantDetailsManager() { } public InMemoryMerchantDetailsManager(Collection merchantDetails) { createMerchant(merchantDetails); } public InMemoryMerchantDetailsManager(Map merchantDetails) { this.merchantDetails = merchantDetails; } /** * 这个暂时还未定义,后期版本进行 * @param merchants 属性配置 */ public InMemoryMerchantDetailsManager(Properties merchants) { } /** * 创建商户 * * @param merchants 商户信息 */ @Override public void createMerchant(Collection merchants) { for (PaymentPlatformMerchantDetails merchant : merchants) { this.createMerchant(merchant); } } /** * 创建商户 * * @param merchant 商户信息 */ @Override public void createMerchant(PaymentPlatformMerchantDetails merchant) { Assert.isTrue(!merchantExists(merchant.getDetailsId()), "商户信息已存在"); InMemoryMerchantDetailsManager.setPayMessageConfigurer(merchant.getPayService(), merchant, configurer); merchantDetails.put(merchant.getDetailsId(), merchant); } protected static void setPayMessageConfigurer(PayService payService, PaymentPlatformMerchantDetails details, PayMessageConfigurer configurer){ PayMessageHandler handler = configurer.getHandler(details.getPaymentPlatform()); if (null != handler){ payService.setPayMessageHandler(handler); } List> interceptors = configurer.getInterceptor(details.getPaymentPlatform()); if (null == interceptors || interceptors.isEmpty()){ return; } for (PayMessageInterceptor interceptor : interceptors){ payService.addPayMessageInterceptor(interceptor); } } /** * 更新商户 * * @param merchant 商户信息 */ @Override public void updateMerchant(PaymentPlatformMerchantDetails merchant) { Assert.isTrue(merchantExists(merchant.getDetailsId()), "商户信息不存在"); merchantDetails.put(merchant.getDetailsId(), merchant); } /** * 删除商户 * * @param id 商户id */ @Override public void deleteMerchant(String id) { merchantDetails.remove(id); } /** * 检查商户是否存在 * * @param id 商户id * @return 检查商户是否存在 */ @Override public boolean merchantExists(String id) { return merchantDetails.containsKey(id); } /** * 设置支付消息配置中心 * * @param configurer 配置 */ @Override public void setPayMessageConfigurer(PayMessageConfigurer configurer) { this.configurer = configurer; } /** * 通过支付商户id加载对应的商户信息列表 * * @param merchantId 支付商户id * @return 商户信息列表 */ @Override public PaymentPlatformMerchantDetails loadMerchantByMerchantId(String merchantId) { PaymentPlatformMerchantDetails details = merchantDetails.get(merchantId); if (null == details) { throw new MerchantNotFoundException(merchantId); } return details; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/JdbcMerchantDetailsManager.java ================================================ package com.egzosn.pay.spring.boot.core.provider; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantNotFoundException; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.UnionPaymentPlatform; import com.egzosn.pay.spring.boot.core.utils.SqlTools; import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.util.Assert; import javax.sql.DataSource; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Arrays; import java.util.Collection; import java.util.List; import static com.egzosn.pay.spring.boot.core.utils.SqlTools.SEPARATED; /** * JDBC支付账户(商户)存储器 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date 2018-11-22 17:18:03
 *                 
*/ public class JdbcMerchantDetailsManager implements MerchantDetailsManager { private static final String TABLE = "merchant_details"; private static final List FIELDS = Arrays.asList("appid", "pay_type", "mch_id", "cert_store_type", "key_private", "key_cert_pwd", "key_public", "key_cert", "notify_url", "return_url", "sign_type", "seller", "sub_app_id", "sub_mch_id", "input_charset", "is_test"); private static final String SELECT_FIELDS = SqlTools.join(FIELDS, SEPARATED); private static final String ID = "details_id"; private static final String DEFAULT_BASE_QUERY_SQL = SqlTools.getSelectSQL(ID + SEPARATED + SELECT_FIELDS, TABLE); private static final String DEFAULT_FIND_BY_ID_SQL = DEFAULT_BASE_QUERY_SQL + " where " + ID + "=?"; private static final String DEFAULT_INSERT_SQL = "insert into " + TABLE + " (" + ID + SEPARATED + SELECT_FIELDS + ") values (" + SqlTools.forQuestionMarkSQL(FIELDS.size() + 1) + ")"; private static final String DEFAULT_UPDATE_SQL = SqlTools.generateUpdateByRowIdString(TABLE, FIELDS, ID).toString(); private static final String DEFAULT_DELETE_SQL = "delete from " + TABLE + " where " + ID + "=?"; public static final String DEFAULT_EXISTS_SQL = "select " + ID + " from " + TABLE + " where " + ID + " = ?"; private JdbcTemplate jdbcTemplate; private String findByIdSql = DEFAULT_FIND_BY_ID_SQL; private String insertSql = DEFAULT_INSERT_SQL; private String updateSql = DEFAULT_UPDATE_SQL; private String deleteSql = DEFAULT_DELETE_SQL; private String existsSql = DEFAULT_EXISTS_SQL; private PayMessageConfigurer configurer; public JdbcMerchantDetailsManager(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public JdbcMerchantDetailsManager(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * 创建商户 * * @param merchants 商户信息 */ @Override public void createMerchant(Collection merchants) { for (CommonPaymentPlatformMerchantDetails merchant : merchants) { this.createMerchant(merchant); } } /** * 创建商户 * * @param merchant 商户信息 */ @Override public void createMerchant(CommonPaymentPlatformMerchantDetails merchant) { Assert.isTrue(!merchantExists(merchant.getDetailsId()), "商户信息已存在"); Object[] args = new Object[]{merchant.getDetailsId(), merchant.getAppId(), merchant.getPayType(), merchant.getMchId(), merchant.getCertStoreType(), merchant.getKeyPrivate(), merchant.getKeyPrivateCertPwd(), merchant.getKeyPublic(), merchant.getKeyCert(), merchant.getNotifyUrl(), merchant.getReturnUrl(), merchant.getSignType(), merchant.getSeller(), merchant.getSubAppId(), merchant.getSubMchId(), merchant.getInputCharset(), merchant.isTest()}; jdbcTemplate.update(insertSql, args); } /** * 更新商户 * * @param merchant 商户信息 */ @Override public void updateMerchant(CommonPaymentPlatformMerchantDetails merchant) { Assert.isTrue(merchantExists(merchant.getDetailsId()), "商户信息不存在"); Object[] args = new Object[]{merchant.getAppId(), merchant.getPayType(), merchant.getMchId(), merchant.getCertStoreType(), merchant.getKeyPrivate(), merchant.getKeyPrivateCertPwd(), merchant.getKeyPublic(), merchant.getKeyCert(), merchant.getNotifyUrl(), merchant.getReturnUrl(), merchant.getSignType(), merchant.getSeller(), merchant.getSubAppId(), merchant.getSubMchId(), merchant.getInputCharset(), merchant.isTest(), merchant.getDetailsId()}; jdbcTemplate.update(updateSql, args); } /** * 删除商户 * * @param id 商户id */ @Override public void deleteMerchant(String id) { jdbcTemplate.update(deleteSql, id); } /** * 检查商户是否存在 * * @param merchantId 商户id * @return 检查商户是否存在 */ @Override public boolean merchantExists(String merchantId) { List ids = jdbcTemplate.queryForList(existsSql, String.class, merchantId); if (ids.size() > 1) { throw new IncorrectResultSizeDataAccessException("出现重复的支付商户id", 1); } return !ids.isEmpty(); } /** * 通过支付商户id加载对应的商户信息列表 * * @param merchantId 支付商户id * @return 商户信息列表 */ @Override public CommonPaymentPlatformMerchantDetails loadMerchantByMerchantId(String merchantId) { List detailss = jdbcTemplate.query(findByIdSql, (ResultSet rs, int i)->{ CommonPaymentPlatformMerchantDetails details = new CommonPaymentPlatformMerchantDetails(); details.setDetailsId(rs.getString(1)); details.setAppId(rs.getString(2)); details.setPayType(rs.getString(3)); details.setMchId(rs.getString(4)); String certStoreType = rs.getString(5); if (StringUtils.isNotEmpty(certStoreType)) { details.setCertStoreType(CertStoreType.valueOf(certStoreType)); } if (details.getCertStoreType() == CertStoreType.INPUT_STREAM) { setKeyPrivate(details, rs); details.setKeyCert(rs.getAsciiStream(9)); } else { details.setKeystore(rs.getString(6)); details.setKeyPublicCert(rs.getString(8)); details.setKeyCert(rs.getString(9)); } details.setKeystorePwd(rs.getString(7)); details.setNotifyUrl(rs.getString(10)); details.setReturnUrl(rs.getString(11)); details.setSignType(rs.getString(12)); details.setSeller(rs.getString(13)); details.setSubAppId(rs.getString(14)); details.setSubMchId(rs.getString(15)); details.setInputCharset(rs.getString(16)); details.setTest(rs.getBoolean(17)); PayService payService = details.initService().getPayService(); InMemoryMerchantDetailsManager.setPayMessageConfigurer(payService, details, configurer); return details; }, merchantId); int size = detailss != null ? detailss.size() : 0; if (size == 0) { throw new MerchantNotFoundException(merchantId); } else if (size > 1) { throw new IncorrectResultSizeDataAccessException(1, size); } else { return detailss.get(0); } } public void setKeyPrivate(CommonPaymentPlatformMerchantDetails details, ResultSet rs) throws SQLException { if (UnionPaymentPlatform.platformName.equals(details.getPayType())) { details.setKeystore(rs.getAsciiStream(6)); details.setKeyPublicCert(rs.getAsciiStream(8)); } else { details.setKeyPrivate(rs.getString(6)); details.setKeyPublic(rs.getString(8)); } } public String getFindByIdSql() { return findByIdSql; } public void setFindByIdSql(String findByIdSql) { this.findByIdSql = findByIdSql; } public String getInsertSql() { return insertSql; } public void setInsertSql(String insertSql) { this.insertSql = insertSql; } public String getUpdateSql() { return updateSql; } public void setUpdateSql(String updateSql) { this.updateSql = updateSql; } public String getDeleteSql() { return deleteSql; } public void setDeleteSql(String deleteSql) { this.deleteSql = deleteSql; } public String getExistsSql() { return existsSql; } public void setExistsSql(String existsSql) { this.existsSql = existsSql; } /** * 设置支付消息配置中心 * * @param configurer 配置 */ @Override public void setPayMessageConfigurer(PayMessageConfigurer configurer) { this.configurer = configurer; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/MerchantDetailsManager.java ================================================ package com.egzosn.pay.spring.boot.core.provider; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetails; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; import java.util.Collection; import java.util.List; /** * 商户列表管理器 * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/4/2 14:44.
 *         
*/ public interface MerchantDetailsManager extends MerchantDetailsService { /** * 创建商户 * @param merchant 商户信息 */ void createMerchant(T merchant); /** * 创建商户 * @param merchants 商户信息 */ void createMerchant(Collection merchants); /** * 更新商户 * @param merchant 商户信息 */ void updateMerchant(T merchant); /** * 删除商户 * @param id 商户id */ void deleteMerchant(String id); /** * 检查商户是否存在 * @param id 商户id * @return 检查商户是否存在 */ boolean merchantExists(String id); /** * 设置支付消息配置中心 * @param configurer 配置 */ void setPayMessageConfigurer(PayMessageConfigurer configurer); } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/AliPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.ali.api.AliPayConfigStorage; import com.egzosn.pay.ali.api.AliPayService; import com.egzosn.pay.ali.bean.AliTransactionType; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; /** * 支付宝支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(AliPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(AliPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.ali.api.AliPayConfigStorage") public class AliPaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "aliPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof AliPayConfigStorage) { return new AliPayService((AliPayConfigStorage) payConfigStorage); } AliPayConfigStorage configStorage = new AliPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setPid(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setSeller(payConfigStorage.getSeller()); configStorage.setKeyPrivate(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { final CommonPaymentPlatformMerchantDetails commonPaymentPlatformMerchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setAppAuthToken(commonPaymentPlatformMerchantDetails.getSubAppId()); certKeyPublic(configStorage, commonPaymentPlatformMerchantDetails); } return new AliPayService(configStorage); } private static void certKeyPublic(AliPayConfigStorage aliPayConfigStorage, CommonPaymentPlatformMerchantDetails payConfigStorage) { final String keyPublicCert = payConfigStorage.getKeyPublic(); //这里通过兼容的方式去处理,匹配尾缀如果为证书文件的话就当证书处理 if (!keyPublicCert.endsWith(".crt")) { return; } //设置为证书方式 aliPayConfigStorage.setCertSign(true); //设置证书存储方式,这里为路径 aliPayConfigStorage.setCertStoreType(payConfigStorage.getCertStoreType()); String[] keyCert = payConfigStorage.getKeyCert().toString().split(","); aliPayConfigStorage.setMerchantCert(keyCert[0]); aliPayConfigStorage.setAliPayRootCert(keyCert[1]); aliPayConfigStorage.setAliPayCert(payConfigStorage.getKeyPublic()); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return AliTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/FuiouPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.fuiou.api.FuiouPayConfigStorage; import com.egzosn.pay.fuiou.api.FuiouPayService; import com.egzosn.pay.fuiou.bean.FuiouTransactionType; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; /** * 富友支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(FuiouPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(FuiouPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.fuiou.api.FuiouPayConfigStorage") public class FuiouPaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "fuiouPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof FuiouPayConfigStorage) { return new FuiouPayService((FuiouPayConfigStorage) payConfigStorage); } FuiouPayConfigStorage configStorage = new FuiouPayConfigStorage(); configStorage.setMchntCd(payConfigStorage.getPid()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); return new FuiouPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return FuiouTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/PaymentPlatforms.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import java.util.HashMap; import java.util.Map; /** * 支付平台集 * * @author egan *
 * email egzosn@gmail.com
 * date  2019/4/9 15:57.
 * 
*/ public final class PaymentPlatforms { private static final Map PAYMENT_PLATFORMS = new HashMap(); /** * 加载支付平台 * * @param platform 支付平台 */ public static void loadPaymentPlatform(PaymentPlatform platform) { PAYMENT_PLATFORMS.put(platform.getPlatform(), platform); } /** * 获取所有的支付平台 * * @return 所有的支付平台 */ public static Map getPaymentPlatforms() { return PAYMENT_PLATFORMS; } /** * 通过支付平台名称与交易类型(支付类型)名称或者交易类型 * * @param platformName 支付平台名称 * @param transactionTypeName 交易类型名称 * @return 交易类型 */ public static TransactionType getTransactionType(String platformName, String transactionTypeName) { PaymentPlatform platform = getPaymentPlatform(platformName); return platform.getTransactionType(transactionTypeName); } /** * 通过支付平台名称与交易类型(支付类型)名称或者交易类型 * * @param platformName 支付平台名称 * @return 交易类型 */ public static PaymentPlatform getPaymentPlatform(String platformName) { PaymentPlatform platform = PAYMENT_PLATFORMS.get(platformName); return platform; } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/PayoneerPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.payoneer.api.PayoneerConfigStorage; import com.egzosn.pay.payoneer.api.PayoneerPayService; import com.egzosn.pay.payoneer.bean.PayoneerTransactionType; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; /** * P卡(派安盈)支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(PayoneerPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(PayoneerPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.payoneer.api.PayoneerConfigStorage") public class PayoneerPaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "payoneerPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof PayoneerConfigStorage) { return new PayoneerPayService((PayoneerConfigStorage) payConfigStorage); } PayoneerConfigStorage configStorage = new PayoneerConfigStorage(); configStorage.setProgramId(payConfigStorage.getPid()); configStorage.setUserName(payConfigStorage.getSeller()); configStorage.setApiPassword(payConfigStorage.getKeyPrivate()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); return new PayoneerPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return PayoneerTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/PaypalPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.paypal.api.PayPalConfigStorage; import com.egzosn.pay.paypal.api.PayPalPayService; import com.egzosn.pay.paypal.bean.PayPalTransactionType; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; /** * 贝宝支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(PaypalPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(PaypalPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.paypal.api.PayPalConfigStorage") public class PaypalPaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "paypalPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof PayPalConfigStorage) { return new PayPalPayService((PayPalConfigStorage) payConfigStorage); } PayPalConfigStorage configStorage = new PayPalConfigStorage(); configStorage.setClientID(payConfigStorage.getPid()); configStorage.setClientSecret(payConfigStorage.getKeyPrivate()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); //取消按钮转跳地址,这里用异步通知地址的兼容的做法 configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); return new PayPalPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return PayPalTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/PaypalV2PaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.paypal.api.PayPalConfigStorage; import com.egzosn.pay.paypal.v2.api.PayPalPayService; import com.egzosn.pay.paypal.v2.bean.PayPalTransactionType; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; /** * 贝宝支付平台 * * @author egan *
 * email egan@egzosn.com
 * date  2021/10/7.
 * 
*/ @Configuration(PaypalV2PaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(PaypalV2PaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.paypal.api.PayPalConfigStorage") public class PaypalV2PaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "paypalV2Pay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof PayPalConfigStorage) { return new PayPalPayService((PayPalConfigStorage) payConfigStorage); } PayPalConfigStorage configStorage = new PayPalConfigStorage(); configStorage.setClientID(payConfigStorage.getPid()); configStorage.setClientSecret(payConfigStorage.getKeyPrivate()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); //取消按钮转跳地址,这里用异步通知地址的兼容的做法 configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); return new PayPalPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return PayPalTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/UnionPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.union.api.UnionPayConfigStorage; import com.egzosn.pay.union.api.UnionPayService; import com.egzosn.pay.union.bean.UnionTransactionType; /** * 银联支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(UnionPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(UnionPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.union.api.UnionPayConfigStorage") public class UnionPaymentPlatform implements PaymentPlatform { protected final Log LOG = LogFactory.getLog(UnionPaymentPlatform.class); public static final String PLATFORM_NAME = "unionPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof UnionPayConfigStorage) { return new UnionPayService((UnionPayConfigStorage) payConfigStorage); } UnionPayConfigStorage configStorage = new UnionPayConfigStorage(); configStorage.setMerId(payConfigStorage.getPid()); //是否为证书签名 configStorage.setCertSign(true); configStorage.setPid(payConfigStorage.getPid()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { CommonPaymentPlatformMerchantDetails merchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; //设置证书对应的存储方式 configStorage.setCertStoreType(merchantDetails.getCertStoreType()); try { //中级证书路径 configStorage.setAcpMiddleCert(merchantDetails.getKeyPublicCertInputStream()); //根证书路径 configStorage.setAcpRootCert(merchantDetails.getKeyCertInputStream()); // 私钥证书路径 configStorage.setKeyPrivateCert(merchantDetails.getKeystoreInputStream()); //这里转变为流的方式 configStorage.setCertStoreType(CertStoreType.INPUT_STREAM); } catch (IOException e) { LOG.error(e); } //私钥证书对应的密码 configStorage.setKeyPrivateCertPwd(merchantDetails.getKeystorePwd()); } return new UnionPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return UnionTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/WxPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.wx.api.WxPayConfigStorage; import com.egzosn.pay.wx.api.WxPayService; import com.egzosn.pay.wx.bean.WxTransactionType; /** * 微信支付平台 * * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ @Configuration(WxPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(WxPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.wx.api.WxPayConfigStorage") public class WxPaymentPlatform extends WxPayConfigStorage implements PaymentPlatform { protected final Log LOG = LogFactory.getLog(WxPaymentPlatform.class); public static final String PLATFORM_NAME = "wxPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { return getPayService(payConfigStorage, null); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { if (payConfigStorage instanceof WxPayConfigStorage) { WxPayService wxPayService = new WxPayService((WxPayConfigStorage) payConfigStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } WxPayConfigStorage configStorage = new WxPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setMchId(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setKeyPrivate(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { CommonPaymentPlatformMerchantDetails merchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setSubAppId(merchantDetails.getSubAppId()); configStorage.setSubMchId(merchantDetails.getSubMchId()); if (null != merchantDetails.getKeyCert()) { if (null == httpConfigStorage) { httpConfigStorage = new HttpConfigStorage(); } httpConfigStorage.setCertStoreType(merchantDetails.getCertStoreType()); try { httpConfigStorage.setKeystore(merchantDetails.getKeyCertInputStream()); } catch (IOException e) { LOG.error(e); } httpConfigStorage.setCertStoreType(CertStoreType.INPUT_STREAM); httpConfigStorage.setStorePassword(merchantDetails.getKeystorePwd()); } } WxPayService wxPayService = new WxPayService(configStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return WxTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/WxV3CombinePaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.wx.v3.api.WxCombinePayService; import com.egzosn.pay.wx.v3.api.WxPayConfigStorage; import com.egzosn.pay.wx.v3.bean.WxTransactionType; /** * 微信V3合单支付平台 * * @author egan *
 * email egan@egzosn.com
 * date  2021/10/7.
 * 
*/ @Configuration(WxV3CombinePaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(WxV3CombinePaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.wx.v3.api.WxPayConfigStorage") public class WxV3CombinePaymentPlatform extends WxPayConfigStorage implements PaymentPlatform { private final Log LOG = LogFactory.getLog(WxV3CombinePaymentPlatform.class); public static final String PLATFORM_NAME = "wxV3CombinePay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { return getPayService(payConfigStorage, null); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { if (payConfigStorage instanceof WxPayConfigStorage) { WxCombinePayService wxPayService = new WxCombinePayService((WxPayConfigStorage) payConfigStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } WxPayConfigStorage configStorage = new WxPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setMchId(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setV3ApiKey(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); //是否为证书签名 configStorage.setCertSign(true); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { CommonPaymentPlatformMerchantDetails merchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setSubAppId(merchantDetails.getSubAppId()); configStorage.setSubMchId(merchantDetails.getSubMchId()); if (null != merchantDetails.getKeyCert()) { configStorage.setCertStoreType(merchantDetails.getCertStoreType()); try { configStorage.setApiClientKeyP12(merchantDetails.getKeyCertInputStream()); } catch (IOException e) { LOG.error(e); } configStorage.setCertStoreType(CertStoreType.INPUT_STREAM); } } WxCombinePayService wxPayService = new WxCombinePayService(configStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return WxTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/WxV3PaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.wx.v3.api.WxPayConfigStorage; import com.egzosn.pay.wx.v3.api.WxPayService; import com.egzosn.pay.wx.v3.bean.WxTransactionType; /** * 微信V3支付平台 * * @author egan *
 * email egan@egzosn.com
 * date  2021/10/7.
 * 
*/ @Configuration(WxV3PaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(WxV3PaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.wx.v3.api.WxPayConfigStorage") public class WxV3PaymentPlatform extends WxPayConfigStorage implements PaymentPlatform { private final Log LOG = LogFactory.getLog(WxV3PaymentPlatform.class); public static final String PLATFORM_NAME = "wxV3Pay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { return getPayService(payConfigStorage, null); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { if (payConfigStorage instanceof WxPayConfigStorage) { WxPayService wxPayService = new WxPayService((WxPayConfigStorage) payConfigStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } WxPayConfigStorage configStorage = new WxPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setMchId(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setV3ApiKey(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { CommonPaymentPlatformMerchantDetails merchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setSubAppId(merchantDetails.getSubAppId()); configStorage.setSubMchId(merchantDetails.getSubMchId()); if (null != merchantDetails.getKeyCert()) { configStorage.setCertStoreType(merchantDetails.getCertStoreType()); try { configStorage.setApiClientKeyP12(merchantDetails.getKeyCertInputStream()); } catch (IOException e) { LOG.error(e); } configStorage.setCertStoreType(CertStoreType.INPUT_STREAM); } } WxPayService wxPayService = new WxPayService(configStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return WxTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/WxV3ProfitSharingPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.wx.v3.api.WxPayConfigStorage; import com.egzosn.pay.wx.v3.api.WxProfitSharingService; import com.egzosn.pay.wx.v3.bean.WxTransactionType; /** * 微信V3分账平台 * * @author egan *
 * email egan@egzosn.com
 * date  2021/10/7.
 * 
*/ @Configuration(WxV3ProfitSharingPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(WxV3ProfitSharingPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.wx.v3.api.WxPayConfigStorage") public class WxV3ProfitSharingPlatform extends WxPayConfigStorage implements PaymentPlatform { private final Log LOG = LogFactory.getLog(WxV3ProfitSharingPlatform.class); public static final String PLATFORM_NAME = "wxV3ProfitSharing"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { return getPayService(payConfigStorage, null); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { if (payConfigStorage instanceof WxPayConfigStorage) { WxProfitSharingService wxPayService = new WxProfitSharingService((WxPayConfigStorage) payConfigStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } WxPayConfigStorage configStorage = new WxPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setMchId(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setV3ApiKey(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); //是否为证书签名 if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { CommonPaymentPlatformMerchantDetails merchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setSubAppId(merchantDetails.getSubAppId()); configStorage.setSubMchId(merchantDetails.getSubMchId()); if (null != merchantDetails.getKeyCert()) { configStorage.setCertStoreType(merchantDetails.getCertStoreType()); try { configStorage.setApiClientKeyP12(merchantDetails.getKeyCertInputStream()); } catch (IOException e) { LOG.error(e); } configStorage.setCertStoreType(CertStoreType.INPUT_STREAM); } } WxProfitSharingService wxPayService = new WxProfitSharingService(configStorage); wxPayService.setRequestTemplateConfigStorage(httpConfigStorage); return wxPayService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return WxTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/provider/merchant/platform/YoudianPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.core.provider.merchant.platform; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Configuration; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.str.StringUtils; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.wx.youdian.api.WxYouDianPayConfigStorage; import com.egzosn.pay.wx.youdian.api.WxYouDianPayService; import com.egzosn.pay.wx.youdian.bean.YoudianTransactionType; /** * 友店支付平台 * * @author egan *
 *         email egzosn@gmail.com
 *         date  2019/4/4 14:35.
 *         
*/ @Configuration(YoudianPaymentPlatform.PLATFORM_NAME) @ConditionalOnMissingBean(YoudianPaymentPlatform.class) @ConditionalOnClass(name = "com.egzosn.pay.wx.youdian.api.WxYouDianPayConfigStorage") public class YoudianPaymentPlatform implements PaymentPlatform { public static final String PLATFORM_NAME = "youdianPay"; @Deprecated public static final String platformName = PLATFORM_NAME; /** * 获取商户平台 * * @return 商户平台 */ @Override public String getPlatform() { return PLATFORM_NAME; } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof WxYouDianPayConfigStorage) { return new WxYouDianPayService((WxYouDianPayConfigStorage) payConfigStorage); } WxYouDianPayConfigStorage configStorage = new WxYouDianPayConfigStorage(); configStorage.setKeyPrivate(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setSignType(payConfigStorage.getSignType()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setSeller(payConfigStorage.getSeller()); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setTest(payConfigStorage.isTest()); return new WxYouDianPayService(configStorage); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { if (StringUtils.isEmpty(name)) { return null; } return YoudianTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot/src/main/java/com/egzosn/pay/spring/boot/core/utils/SqlTools.java ================================================ package com.egzosn.pay.spring.boot.core.utils; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Types; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * jdbc sql生成语句生产 * * @author ZaoSheng * Wed Nov 162 17:31:32 CST 2015 */ public class SqlTools { public static final String SEPARATED = ", "; private static final Pattern PATTERN = Pattern.compile(":([0-9A-Za-z_]+)[" + SEPARATED + "]?"); /** * 获取统计的sql * * @param sql 原始sql * @return 转化后的sql */ public static String getCountSQL(final String sql) { return getCountSQL(sql, null); } /** * 获取统计的sql * * @param sql 原始sql * @return 转化后的sql */ public static String getCountOracleSQL(final String sql) { return getCountOracleSQL(sql, null); } /** * 获取统计的sql * * @param sql 原始sql * @param countField 需要统计的字段 * @return 转化后的sql */ public static String getCountSQL(final String sql, String countField) { String countSql = String.format("SELECT COUNT(%s) ", null == countField ? "*" : countField); String upperSql = sql.toUpperCase(); int start = upperSql.indexOf("FROM "); int end = upperSql.lastIndexOf("ORDER BY "); countSql += sql.substring(start, end == -1 ? sql.length() : end); return countSql; } /** * 获取统计的sql * * @param sql 原始sql * @param countField 需要统计的字段 * @return 转化后的sql */ public static String getCountOracleSQL(final String sql, String countField) { String countSql = String.format("SELECT COUNT(%s) ", null == countField ? "*" : countField); String upperSql = sql.toUpperCase().replace("SELECT * FROM ( ", "").replace(" ) WHERE ROWNUM BETWEEN %s AND %s", ""); int start = upperSql.indexOf("FROM "); int end = upperSql.lastIndexOf("ORDER BY "); countSql += sql.substring(start, end == -1 ? sql.length() : end); return countSql; } /** * 移除sql的group部分 * * @param sql 原始sql * @return 转化后的sql */ public static String removeGROUP(final String sql) { String upperSql = sql.toUpperCase(); int end = upperSql.indexOf(" GROUP "); return -1 == end ? sql : sql.substring(0, end); } /** * 获取sql * * @param select 需要查询的字段 * @param tableName 表名 * @return sql */ public static String getSelectSQL(String select, String tableName) { if (null == select || "".equals(select)) { select = "*"; } return String.format("select %s from %s ", select, tableName); } /** * 获取sql * * @param select 需要查询的字段 * @param tableName 表名 * @param alias 别名 * @param where 条件开始的语句 * @return 拼装好的sql */ public static String getSQL(String select, String tableName, String alias, String where) { return String.format("%s %s %s", getSelectSQL(select, tableName), alias, where); } /** * 拼接分页部分 * * @param pageNumber 页号 * @param pageSize 每页大小 * @return 拼装 分页sql */ public static String forPaginate(int pageNumber, int pageSize) { int offset = pageSize * (pageNumber - 1); return String.format(" limit %s,%s", offset, pageSize); } /** * 拼接分页部分 * * @param sql sql * @param pageNumber 页号 * @param pageSize 每页大小 * @return 拼装 分页sql */ public static String forPaginate(String sql, int pageNumber, int pageSize) { int offset = pageSize * (pageNumber - 1); String sqltmp = String.format("SELECT * FROM (SELECT ROWNUM RN,a.* FROM ( %s ) a WHERE ROWNUM <= %s) WHERE RN >%s", sql, offset + pageSize, offset); return sqltmp; } /** * 设置 参数 * * @param ps 代替对象 * @param params 参数 * @throws SQLException 设置参数异常 */ public static void fillStatement(PreparedStatement ps, List params) throws SQLException { if (null == params || params.isEmpty()) { return; } int i = 0; for (Object param : params) { if (param instanceof List) { fillStatement(ps, (List) param); ps.addBatch(); continue; } if (param instanceof Object[]) { fillStatement(ps, (Object[]) param); ps.addBatch(); continue; } if (null == param) { ps.setNull(++i, Types.OTHER); continue; } ps.setObject(++i, param); } } /** * 设置 参数 * * @param ps 代替对象 * @param params 参数 * @throws SQLException 设置参数异常 */ public static void fillStatement(PreparedStatement ps, Object... params) throws SQLException { if (null == params) { return; } if (params instanceof Object[][]) { for (Object[] v : (Object[][]) params) { fillStatement(ps, v); ps.addBatch(); } } else { int i = 0; for (Object param : params) { if (null == param) { ps.setNull(++i, Types.OTHER); continue; } ps.setObject(++i, param); } } } /** * 生成插入语句 * * @param tableName 表名 * @param keyColumnNames 数据库列集 * @return 插入语句 */ public static StringBuilder generateInsertString(String tableName, List keyColumnNames) { StringBuilder sql = new StringBuilder(); sql.append("insert into ").append(tableName).append("("); StringBuilder temp = new StringBuilder(") values("); boolean flag = false; for (String colName : keyColumnNames) { if (flag) { sql.append(", "); temp.append(", "); } sql.append("").append(colName).append(""); temp.append("?"); flag = true; } return sql.append(temp.toString()).append(")"); } /** * 生成更新语句 * * @param tableName 表名 * @param keyColumnNames 数据库列集 * @param idColumn 主键列 * @return 更新语句 */ public static StringBuilder generateUpdateByRowIdString(String tableName, List keyColumnNames, String idColumn) { StringBuilder sql = new StringBuilder(); sql.append("update ").append(tableName).append(" set "); int i = 0; for (String colName : keyColumnNames) { if (i != 0) { sql.append(", "); } sql.append("").append(colName).append(" = ? "); i++; } // keyColumnNames.add(idColumn); sql.append(" where ").append(idColumn).append(" = ?"); return sql; } /** * 通过 Map 获取保存的sql * * @param table 表名 * @param attrs Map属性集 * @param paras 参数集 * @return 生成sql */ public static StringBuilder forMapSave(String table, Map attrs, List paras) { StringBuilder sql = new StringBuilder(); sql.append("insert into ").append(table).append("("); StringBuilder temp = new StringBuilder(") values("); for (Map.Entry entry : attrs.entrySet()) { if (null == entry.getValue()) { continue; } if (paras.size() > 0) { sql.append(", "); temp.append(", "); } sql.append(' ').append(entry.getKey()).append(' '); temp.append("?"); paras.add(entry.getValue()); } sql.append(temp).append(")"); return sql; } /** * 生成更新的sql * * @param table 表名 * @param attrs 更新的属性 * @param where 条件部分 * @param whereVal 条件对应的值 * @param paras 参数集 * @return 更新的sql */ public static StringBuilder forMapUpdate(String table, Map attrs, String where, List whereVal, List paras) { StringBuilder sql = new StringBuilder(); sql.append("update ").append(table).append(" set "); for (Map.Entry entry : attrs.entrySet()) { if (!paras.isEmpty()) { sql.append(", "); } sql.append(' ').append(entry.getKey()).append(" = ? "); paras.add(entry.getValue()); } sql.append(where); paras.addAll(whereVal); return sql; } /** * 生成更新的sql * * @param table 表名 * @param attrs 更新的属性 * @param where 条件部分 and eq 级别 * @param paras 参数集 * @return 更新的sql */ public static StringBuilder forMapUpdate(String table, Map attrs, Map where, List paras) { boolean flag = false; StringBuilder sql = new StringBuilder(); sql.append("update ").append(table).append(" set "); for (Map.Entry entry : attrs.entrySet()) { if (flag) { sql.append(", "); } sql.append(' ').append(entry.getKey()).append(" = ? "); paras.add(entry.getValue()); flag = true; } sql.append(" where "); for (Map.Entry entry : where.entrySet()) { if (!flag) { sql.append(" and "); } sql.append(' ').append(entry.getKey()).append(" = ? "); paras.add(entry.getValue()); flag = false; } return sql; } /** * 冒号形式的sql转化为问号形式 * * @param sql 原始sql * @param attrs 属性 * @param values 转化后的属性集 * @return 转化后的sql */ public static String forConverSQL(String sql, Map attrs, List values) { Matcher matcher = PATTERN.matcher(sql); String rexp = null; while (matcher.find()) { String group = matcher.group(1); Object ov = attrs.get(group); if (ov instanceof Collection) { StringBuilder sb = new StringBuilder(); Collection vs = (Collection) ov; for (Object v : vs) { sb.append("?,"); values.add(v); } sb.deleteCharAt(sb.length() - 1); rexp = sb.toString(); } else { values.add(ov); rexp = "?"; } sql = sql.replace(String.format(":%s", group), rexp); } return sql; } /** * 根据数组对象生成对应的in部分 * * @param num 生成"?"的数量 * * forQuestionMarkSQL(3) = ?,?,? * @return 问号,逗号隔开 */ public static String forQuestionMarkSQL(int num) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < num; i++) { sb.append("?,"); } sb.deleteCharAt(sb.length() - 1); return sb.toString(); } /** * 将集合以分隔符的形式进行连接成对应字符串 * * @param list 集合 * @param separated 分隔符 * @return 连接字符串 */ public static String join(List list, String separated) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.size(); i++) { if (sb.length() != 0) { sb.append(separated); } sb.append(list.get(i)); } return sb.toString(); } } ================================================ FILE: pay-spring-boot-autoconfigue/pom.xml ================================================ pay-spring-boot-starter-parent com.egzosn 1.0.5 4.0.0 pay-spring-boot-autoconfigue pay-spring-boot-autoconfigue com.egzosn pay-spring-boot ${project.version} ================================================ FILE: pay-spring-boot-autoconfigue/src/main/java/com/egzosn/pay/spring/boot/autoconfigue/PayAutoConfiguration.java ================================================ package com.egzosn.pay.spring.boot.autoconfigue; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import com.egzosn.pay.spring.boot.core.MerchantPayServiceManager; import com.egzosn.pay.spring.boot.core.PayServiceConfigurer; import com.egzosn.pay.spring.boot.core.PayServiceManager; import com.egzosn.pay.spring.boot.core.configurers.DefalutPayMessageConfigurer; import com.egzosn.pay.spring.boot.core.configurers.MerchantDetailsServiceConfigurer; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.MerchantDetailsService; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.FuiouPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PayoneerPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaypalPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaypalV2PaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.UnionPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxV3CombinePaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxV3PaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxV3ProfitSharingPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.YoudianPaymentPlatform; /** * 支付转载配置 * * @author egan *
 *  email egzosn@gmail.com
 *  date  2018/11/21.
 *  
*/ @Configuration @ImportAutoConfiguration({AliPaymentPlatform.class, FuiouPaymentPlatform.class, PayoneerPaymentPlatform.class, PaypalPaymentPlatform.class, UnionPaymentPlatform.class, WxPaymentPlatform.class, WxV3PaymentPlatform.class, WxV3ProfitSharingPlatform.class, WxV3CombinePaymentPlatform.class, PaypalV2PaymentPlatform.class, YoudianPaymentPlatform.class}) public class PayAutoConfiguration { @Autowired(required = false) @Order public void loadPaymentPlatforms(List platforms) { for (PaymentPlatform platform : platforms) { PaymentPlatforms.loadPaymentPlatform(platform); } } @Bean @ConditionalOnMissingBean(MerchantDetailsServiceConfigurer.class) @ConditionalOnBean(PayServiceConfigurer.class) public MerchantDetailsServiceConfigurer detailsServiceConfigurer() { return new MerchantDetailsServiceConfigurer(); } @Bean @ConditionalOnMissingBean(MerchantDetailsService.class) @ConditionalOnBean(PayServiceConfigurer.class) protected MerchantDetailsService configure(PayServiceConfigurer configurer, MerchantDetailsServiceConfigurer merchantDetails, PayMessageConfigurer payMessageConfigurer) { configurer.configure(merchantDetails); configurer.configure(payMessageConfigurer); MerchantDetailsService detailsService = merchantDetails.getBuilder().build(); return detailsService; } @Bean @Order @ConditionalOnBean(MerchantDetailsService.class) @ConditionalOnMissingBean(PayServiceManager.class) public PayServiceManager payServiceManager() { return new MerchantPayServiceManager(); } @Bean @ConditionalOnMissingBean(PayMessageConfigurer.class) public PayMessageConfigurer messageHandlerConfigurer() { return new DefalutPayMessageConfigurer(); } } ================================================ FILE: pay-spring-boot-autoconfigue/src/main/resources/META-INF/spring.factories ================================================ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.egzosn.pay.spring.boot.autoconfigue.PayAutoConfiguration ================================================ FILE: pay-spring-boot-starter/pom.xml ================================================ pay-spring-boot-starter-parent com.egzosn 1.0.5 4.0.0 pay-spring-boot-starter pay-spring-boot-starter com.egzosn pay-spring-boot-autoconfigue ${project.version} ================================================ FILE: pay-spring-boot-starter/src/main/resources/META-INF/spring.providers ================================================ provides: pay-spring-boot-autoconfigue ================================================ FILE: pay-spring-boot-starter-demo/pom.xml ================================================ pay-spring-boot-starter-parent com.egzosn 1.0.5 4.0.0 com.egzosn pay-spring-boot-starter-demo pay-spring-boot-starter-demo jar 17 com.egzosn pay-spring-boot-starter ${project.version} org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java com.egzosn pay-java-web-support ${pay.version} com.egzosn pay-java-ali com.egzosn pay-java-wx ${pay.version} com.egzosn pay-java-union ${pay.version} com.egzosn pay-java-payoneer ${pay.version} com.egzosn pay-java-paypal ${pay.version} com.egzosn pay-java-wx-youdian ${pay.version} com.egzosn pay-java-fuiou ${pay.version} org.springframework.boot spring-boot-devtools true ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/PayApplication.java ================================================ package com.egzosn.pay.spring.boot.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 应用 * @author egan * email egzosn@gmail.com * date 2019/5/27.20:51 */ @SpringBootApplication public class PayApplication { public static void main(String[] args) { SpringApplication.run(PayApplication.class, args); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/config/MerchantPayServiceConfigurer.java ================================================ package com.egzosn.pay.spring.boot.demo.config; import com.egzosn.pay.common.bean.CertStoreType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.PayServiceConfigurer; import com.egzosn.pay.spring.boot.core.configurers.MerchantDetailsServiceConfigurer; import com.egzosn.pay.spring.boot.core.merchant.bean.UnionMerchantDetails; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxPaymentPlatform; import com.egzosn.pay.spring.boot.demo.config.handlers.AliPayMessageHandler; import com.egzosn.pay.spring.boot.demo.config.handlers.WxPayMessageHandler; import com.egzosn.pay.spring.boot.demo.config.interceptor.AliPayMessageInterceptor; import com.egzosn.pay.spring.boot.core.configurers.PayMessageConfigurer; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.PaymentPlatforms; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.WxPaymentPlatform; import com.egzosn.pay.spring.boot.demo.config.handlers.WxPayMessageHandler; import com.egzosn.pay.spring.boot.demo.config.interceptor.AliPayMessageInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; /** * 支付服务配置 * * @author egan * email egzosn@gmail.com * date 2019/5/26.19:25 */ @Configuration public class MerchantPayServiceConfigurer implements PayServiceConfigurer { // @Autowired // private JdbcTemplate jdbcTemplate; @Autowired private AutowireCapableBeanFactory spring; @Autowired private AliPayMessageHandler aliPayMessageHandler; public static PublicKey loadPublicKeyFromString(String keyString) { try { keyString = keyString.replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "").replaceAll("\\s+", ""); return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(keyString))); } catch (NoSuchAlgorithmException e) { throw new UnsupportedOperationException(e); } catch (InvalidKeySpecException e) { throw new IllegalArgumentException(e); } } /** * 商户配置 * * @param merchants 商户配置 */ @Override public void configure(MerchantDetailsServiceConfigurer merchants) { // 数据库文件存放 /doc/sql目录下 // merchants.jdbc() // //是否开启缓存,默认不开启,这里开启缓存 // .cache(true) // .template(jdbcTemplate); //微信请求配置,详情参考https://gitee.com/egzosn/pay-java-parent项目中的使用 // PublicKey publicKey = loadPublicKeyFromString("MIIEFDCCAvygAwIBAgIUcsLvDuUJXG2Cb/kJvjPWI6xi3kYwDQYJKoZIhvcNAQEL\n" + // "BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" + // "FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" + // "Q0EwHhcNMjUwMTA2MDY0MjI3WhcNMzAwMTA1MDY0MjI3WjBuMRgwFgYDVQQDDA9U\n" + // "ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" + // "bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo\n" + // "ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCejehpOA5Q4yen2mjx\n" + // "imNGIwiQThXnt9NPm8ut+A9YON+sBS5bwApy1WZyClUnc0OdGKu0Ygw9jp0qTodN\n" + // "lfLJsR5yLnm4vQY43uYVIHl9dCTOD+ZqYLc+Ld/B+gtYMJbIhgUU142Y7lUIOsmI\n" + // "DbMLPchbxPuajqdav8tL2cnz9MtF5Gw+ZusJ9GBYBeu8/xyQFaq3jD/zWnbGHZ4K\n" + // "hS1LOXmcyTPwZNy9k4ckqcf1x/yy7eH92EsXnXAqhfH+dQcSgYZcK6JLXi2bWyqF\n" + // "UpQZ2DzmhJwQ09bN0a9g4Py1AOYSdj0ZBuaNvHRJVVQK1LLg6vUtfbMPGDwhbyp/\n" + // "S207AgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB\n" + // "kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv\n" + // "aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4\n" + // "RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0\n" + // "MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAk82I3ThSpikhHbtG8pTtJay8gJyIUf+n\n" + // "rn9G8AruSpDvlCxRMJ6QHXLABLx5ko/yG+gGv7P02M3AQbDskxMN430vHRsJ8tyY\n" + // "B8C2QE8AbVHzJ2/K6CirxDxGbclSwJCvdq++uebfnKbM7U5GnfyHprpjT9MLIx0G\n" + // "r+i1CXQ4SCWYt0am84kLwpjDIkPuzqWbIdmNVV9+3lbQilaB6/EQzQxsGeA0FxPV\n" + // "mGJC02hmaPgORKGLZM91Z3xnS/trLU3yF/VxMX5g7QGW9DlHOW2I8Ko/wiZuU3MM\n" + // "WKM0Vp8BB+817Vn8HZ52b53bc85Ffm8tOLlX5kMutV2k8QH7SR/8xg=="); //内存Builder方式 merchants.inMemory() // .ali() // .detailsId("1") // .appid("2016080400165436") // .keyPrivate("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKroe/8h5vC4L6T+B2WdXiVwGsMvUKgb2XsKix6VY3m2wcf6tyzpNRDCNykbIwGtaeo7FshN+qZxdXHLiIam9goYncBit/8ojfLGy2gLxO/PXfzGxYGs0KsDZ+ryVPPmE34ZZ8jiJpR0ygzCFl8pN3QJPJRGTJn5+FTT9EF/9zyZAgMBAAECgYAktngcYC35u7cQXDk+jMVyiVhWYU2ULxdSpPspgLGzrZyG1saOcTIi/XVX8Spd6+B6nmLQeF/FbU3rOeuD8U2clzul2Z2YMbJ0FYay9oVZFfp5gTEFpFRTVfzqUaZQBIjJe/xHL9kQVqc5xHlE/LVA27/Kx3dbC35Y7B4EVBDYAQJBAOhsX8ZreWLKPhXiXHTyLmNKhOHJc+0tFH7Ktise/0rNspojU7o9prOatKpNylp9v6kux7migcMRdVUWWiVe+4ECQQC8PqsuEz7B0yqirQchRg1DbHjh64bw9Kj82EN1/NzOUd53tP9tg+SO97EzsibK1F7tOcuwqsa7n2aY48mQ+y0ZAkBndA2xcRcnvOOjtAz5VO8G7R12rse181HjGfG6AeMadbKg30aeaGCyIxN1loiSfNR5xsPJwibGIBg81mUrqzqBAkB+K6rkaPXJR9XtzvdWb/N3235yPkDlw7Z4MiOVM3RzvR/VMDV7m8lXoeDde2zQyeMOMYy6ztwA6WgE1bhGOnQRAkEAouUBv1sVdSBlsexX15qphOmAevzYrpufKgJIRLFWQxroXMS7FTesj+f+FmGrpPCxIde1dqJ8lqYLTyJmbzMPYw==") // .keyPublic("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIgHnOn7LLILlKETd6BFRJ0GqgS2Y3mn1wMQmyh9zEyWlz5p1zrahRahbXAfCfSqshSNfqOmAQzSHRVjCqjsAw1jyqrXaPdKBmr90DIpIxmIyKXv4GGAkPyJ/6FTFY99uhpiq0qadD/uSzQsefWo0aTvP/65zi3eof7TcZ32oWpwIDAQAB") // .inputCharset("utf-8") // .notifyUrl("http://pay.egzosn.com/payBack1.json") // .returnUrl("http://pay.egzosn.com/payBack1.json") // .pid("2088102169916436") // .seller("2088102169916436") // .signType("RSA") // .test(true) // .and() .wxV3() .detailsId("2") .appId("wx5ce9f1a204c49979") .mchId("1703302548") .v3ApiKey("KDBX2tbrKi9eWFEZW4s3bxGpP30AtXtW") .keyPrivate("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCltaNjUKUcXEQe\n" + "31O3ljZswpRgNMVNVdR2vQt0ymVKZwFcTNrOE28Tmn4UuWkb6HzCTtlOM2mOuX9T\n" + "uE8rkkc+gqrZtTjchotsGu35YO3L2VvADxvd0SUw9rZIqh+/5MybBEpmOwR9p1pr\n" + "bYSwxSWlwx4qt1fNX/uOrjYplcvEp00otlHv3SJh2CyK+vkWP30F18FVTpTf1mdY\n" + "ehMF8aDr9Zlnsdm25Kig14Zly25dsuxiuoagLWIz0031v3byO0iuAxxUhl9ofUHh\n" + "zt2ajshy/DS910N0PE/FCYKbMQEz951ZnAojWI97hXRYnigAEo1VJyB9GBxxPRIT\n" + "fr4KUJGvAgMBAAECggEAVw5L3hs6AuI+L3HoS2SxBwZaaQiQNwbGbfL3F85U1He0\n" + "8Ua3FNiE3Gmnnz+hBrZnBLXj1/+OjxrI17TWcu+QWjjPhTx9uO0+RfcH2qGfjB6O\n" + "4yGM5EXCIi0aqqYls+yByVbBt19+Bn1rNVD+Ctgn5SPSr2JO0GiCgfzoG4TE3nSl\n" + "v9YWhfzbWjrNgQR4npY5UQbL4D86ubZ6I81YnN+MGmxuTxS06fwjQyVH3AQbUp70\n" + "LRmdjQUhsRS2uSmsMmfavLtfyq14ZV2I0KWNADzvGfcTNOtg+XCCohQyJUhEDhtH\n" + "Si8bvsL+Blauu0o8tpFMA1hEIsxdwdvjWAie45yW4QKBgQDUyQTYc/oyJn7HfGLN\n" + "EcUF9qCL0ymH1UepstrnIDiNTZ4n4rFCORlM5wpZe6kZzZqMRMnHEaipk4WWryAN\n" + "z0UjXA+n3j/uoIybvpMjljMHvxzP+IfZwt/XK437bFeiNSNigk8zU7sEw0RD+y77\n" + "Jn6ucmnFxBwpsN4zuFKY+ObhBwKBgQDHXReTD6HLZ12Pf91469D/qvD7jJ7R/1I7\n" + "maPHQB7+VrSHZeZnhy9TOZyONEt3vd2GpYxhdvkUXL4j6FqjYn0tt72PNs/xQhL0\n" + "V3EZsm+YYZ8GOPh24Ij6jPhWLEIvYGLYSBtR7Uq8VWN84A1AUxnw538I8L7qH+7D\n" + "j0PTuSioGQKBgEeqoLgqb7UeZAraKQi6mGpGw5H0gANg4S8Vr0azAnkNEFyMrHkK\n" + "dCwDkOfMj4rCRfBCZtdmajEbH549w4UDL10Wb6txXoUHi/QUvsf4mZ1dT9337gF4\n" + "8h0tbTemKOnYDd/q1bQK2m1jOwXOfudV8srcfCWAxJ+CE4TF6wPcqR5XAoGAYAFs\n" + "gN1eRN2aKKiitsCY/QYM1pZ5RRd3OkxamnE+e6y1cx6XPfPTznhH9BMq5JcCPv0q\n" + "BSWN/UhMKG6Ud2nObl21Y2o56SywhAo35PAQ3YjlU9HLlTO7wyxvys+1b6sy7oSK\n" + "44EqJFfaeSBMQVXDgEd63YtR5N1L1dEAEM1xzsECgYEAxMV8DnXRUpY2tTF0GHLL\n" + "RJBz0OQNbQbpOsUQuMyAN+MGISdbjJISpVOBE1ngUwS1CNGIUaBKUZu5g53ZqF/M\n" + "K3a0qjFJwzzkCaTo802CBcoATYKhQv+xP25s7UU+gS1Qhsa57+j/g0yoSNle02gE\n" + "vOBgNU/g1THHdIVOY4uO64g=") .merchantSerialNumber("72C2EF0EE5095C6D826FF909BE33D623AC62DE46") // .keyPublic("MIIEFDCCAvygAwIBAgIUcsLvDuUJXG2Cb/kJvjPWI6xi3kYwDQYJKoZIhvcNAQEL\n" + // "BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\n" + // "FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\n" + // "Q0EwHhcNMjUwMTA2MDY0MjI3WhcNMzAwMTA1MDY0MjI3WjBuMRgwFgYDVQQDDA9U\n" + // "ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\n" + // "bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo\n" + // "ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCejehpOA5Q4yen2mjx\n" + // "imNGIwiQThXnt9NPm8ut+A9YON+sBS5bwApy1WZyClUnc0OdGKu0Ygw9jp0qTodN\n" + // "lfLJsR5yLnm4vQY43uYVIHl9dCTOD+ZqYLc+Ld/B+gtYMJbIhgUU142Y7lUIOsmI\n" + // "DbMLPchbxPuajqdav8tL2cnz9MtF5Gw+ZusJ9GBYBeu8/xyQFaq3jD/zWnbGHZ4K\n" + // "hS1LOXmcyTPwZNy9k4ckqcf1x/yy7eH92EsXnXAqhfH+dQcSgYZcK6JLXi2bWyqF\n" + // "UpQZ2DzmhJwQ09bN0a9g4Py1AOYSdj0ZBuaNvHRJVVQK1LLg6vUtfbMPGDwhbyp/\n" + // "S207AgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB\n" + // "kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv\n" + // "aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4\n" + // "RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0\n" + // "MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAk82I3ThSpikhHbtG8pTtJay8gJyIUf+n\n" + // "rn9G8AruSpDvlCxRMJ6QHXLABLx5ko/yG+gGv7P02M3AQbDskxMN430vHRsJ8tyY\n" + // "B8C2QE8AbVHzJ2/K6CirxDxGbclSwJCvdq++uebfnKbM7U5GnfyHprpjT9MLIx0G\n" + // "r+i1CXQ4SCWYt0am84kLwpjDIkPuzqWbIdmNVV9+3lbQilaB6/EQzQxsGeA0FxPV\n" + // "mGJC02hmaPgORKGLZM91Z3xnS/trLU3yF/VxMX5g7QGW9DlHOW2I8Ko/wiZuU3MM\n" + // "WKM0Vp8BB+817Vn8HZ52b53bc85Ffm8tOLlX5kMutV2k8QH7SR/8xg==") // .keyPublicId("72C2EF0EE5095C6D826FF909BE33D623AC62DE46") .notifyUrl("http://pay.egzosn.com/payBack2.json") .returnUrl("http://pay.egzosn.com/payBack2.json") .inputCharset("utf-8") .and() ; /* //------------内存手动方式------------------ UnionMerchantDetails unionMerchantDetails = new UnionMerchantDetails(); unionMerchantDetails.detailsId("3"); //内存方式的时候这个必须设置 unionMerchantDetails.setCertSign(true); unionMerchantDetails.setMerId("700000000000001"); //公钥,验签证书链格式: 中级证书路径; unionMerchantDetails.setAcpMiddleCert("D:/certs/acp_test_middle.cer"); //公钥,根证书路径 unionMerchantDetails.setAcpRootCert("D:/certs/acp_test_root.cer"); //私钥, 私钥证书格式: 私钥证书路径 unionMerchantDetails.setKeyPrivateCert("D:/certs/acp_test_sign.pfx"); //私钥证书对应的密码 unionMerchantDetails.setKeyPrivateCertPwd("000000"); //证书的存储方式 unionMerchantDetails.setCertStoreType(CertStoreType.PATH); unionMerchantDetails.setNotifyUrl("http://127.0.0.1/payBack4.json"); // 无需同步回调可不填 app填这个就可以 unionMerchantDetails.setReturnUrl("http://127.0.0.1/payBack4.json"); unionMerchantDetails.setInputCharset("UTF-8"); unionMerchantDetails.setSignType("RSA2"); unionMerchantDetails.setTest(true); //手动加入商户容器中 merchants.inMemory().addMerchantDetails(unionMerchantDetails);*/ } /** * 商户配置 * * @param configurer 支付消息配置 */ @Override public void configure(PayMessageConfigurer configurer) { PaymentPlatform aliPaymentPlatform = PaymentPlatforms.getPaymentPlatform(AliPaymentPlatform.PLATFORM_NAME); configurer.addHandler(aliPaymentPlatform, aliPayMessageHandler); configurer.addInterceptor(aliPaymentPlatform, spring.getBean(AliPayMessageInterceptor.class)); configurer.addHandler(PaymentPlatforms.getPaymentPlatform(WxPaymentPlatform.PLATFORM_NAME), new WxPayMessageHandler()); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/config/MyAliPaymentPlatform.java ================================================ package com.egzosn.pay.spring.boot.demo.config; import com.egzosn.pay.ali.api.AliPayConfigStorage; import com.egzosn.pay.ali.api.AliPayService; import com.egzosn.pay.ali.bean.AliTransactionType; import com.egzosn.pay.common.api.PayConfigStorage; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.TransactionType; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.spring.boot.core.merchant.bean.CommonPaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.provider.merchant.platform.AliPaymentPlatform; /** * 支付宝支付平台,自定义支付宝平台支持证书方式 * 所有支付平台都可以使用这种定制的方式进行覆盖 * 使用案例 * @author egan *
 *                 email egzosn@gmail.com
 *                 date  2019/4/4 14:35.
 *                 
*/ //@Component(AliPaymentPlatform.PLATFORM_NAME) public class MyAliPaymentPlatform extends AliPaymentPlatform { /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage) { if (payConfigStorage instanceof AliPayConfigStorage) { return new AliPayService((AliPayConfigStorage) payConfigStorage); } AliPayConfigStorage configStorage = new AliPayConfigStorage(); configStorage.setInputCharset(payConfigStorage.getInputCharset()); configStorage.setAppId(payConfigStorage.getAppId()); configStorage.setPid(payConfigStorage.getPid()); configStorage.setAttach(payConfigStorage.getAttach()); configStorage.setSeller(payConfigStorage.getSeller()); configStorage.setKeyPrivate(payConfigStorage.getKeyPrivate()); configStorage.setKeyPublic(payConfigStorage.getKeyPublic()); configStorage.setNotifyUrl(payConfigStorage.getNotifyUrl()); configStorage.setReturnUrl(payConfigStorage.getReturnUrl()); configStorage.setPayType(payConfigStorage.getPayType()); configStorage.setTest(payConfigStorage.isTest()); configStorage.setSignType(payConfigStorage.getSignType()); if (payConfigStorage instanceof CommonPaymentPlatformMerchantDetails) { final CommonPaymentPlatformMerchantDetails commonPaymentPlatformMerchantDetails = (CommonPaymentPlatformMerchantDetails) payConfigStorage; configStorage.setAppAuthToken(commonPaymentPlatformMerchantDetails.getSubAppId()); certKeyPublic(configStorage, commonPaymentPlatformMerchantDetails); } return new AliPayService(configStorage); } /** * 设置证书公钥信息 * 普通公钥方式与证书公钥方式为两者取其一的方式 * * @param aliPayConfigStorage 支付宝配置信息 * @param payConfigStorage 配置信息 */ private static void certKeyPublic(AliPayConfigStorage aliPayConfigStorage, CommonPaymentPlatformMerchantDetails payConfigStorage) { final String keyPublicCert = payConfigStorage.getKeyPublic(); //这里通过兼容的方式去处理,匹配尾缀如果为证书文件的话就当证书处理 if (!keyPublicCert.endsWith(".crt")) { return; } //设置为证书方式 aliPayConfigStorage.setCertSign(true); //设置证书存储方式,这里为路径 aliPayConfigStorage.setCertStoreType(payConfigStorage.getCertStoreType()); String[] keyCert = payConfigStorage.getKeyCert().toString().split(","); aliPayConfigStorage.setMerchantCert(keyCert[0]); aliPayConfigStorage.setAliPayRootCert(keyCert[1]); aliPayConfigStorage.setAliPayCert(payConfigStorage.getKeyPublic()); } /** * 获取支付平台对应的支付服务 * * @param payConfigStorage 支付配置 * @param httpConfigStorage 网络配置 * @return 支付服务 */ @Override public PayService getPayService(PayConfigStorage payConfigStorage, HttpConfigStorage httpConfigStorage) { PayService payService = getPayService(payConfigStorage); payService.setRequestTemplateConfigStorage(httpConfigStorage); return payService; } @Override public TransactionType getTransactionType(String name) { return AliTransactionType.valueOf(name); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/config/handlers/AliPayMessageHandler.java ================================================ package com.egzosn.pay.spring.boot.demo.config.handlers; import com.egzosn.pay.ali.api.AliPayService; import com.egzosn.pay.ali.bean.AliPayMessage; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.bean.PayOutMessage; import com.egzosn.pay.common.exception.PayErrorException; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.util.Map; /** * 支付宝支付回调处理器 * Created by ZaoSheng on 2016/6/1. * */ @Component public class AliPayMessageHandler implements PayMessageHandler { /** * 处理支付回调消息的处理器接口 * * @param payMessage 支付消息 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param payService 支付服务 * @return xml, text格式的消息,如果在异步规则里处理的话,可以返回null * @throws PayErrorException 支付错误异常 */ @Override public PayOutMessage handle(AliPayMessage payMessage, Map context, AliPayService payService) throws PayErrorException { //com.egzosn.pay.demo.entity.PayType.getPayService()#48 Object payId = payService.getPayConfigStorage().getAttach(); Map message = payMessage.getPayMessage(); //交易状态 String trade_status = (String) message.get("trade_status"); //上下文对象中获取账单 // AmtApply amtApply = (AmtApply)context.get("amtApply"); //日志存储 // amtPaylogService.createAmtPaylogByCallBack(amtApply, message.toString()); //交易完成 if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) { BigDecimal payAmount = new BigDecimal((String) message.get("total_fee")); return payService.successPayOutMessage(payMessage); }/* else if ("WAIT_BUYER_PAY".equals(trade_status) || "TRADE_CLOSED".equals(trade_status)) { }*/ return payService.getPayOutMessage("fail", "失败"); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/config/handlers/WxPayMessageHandler.java ================================================ package com.egzosn.pay.spring.boot.demo.config.handlers; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayService; import com.egzosn.pay.common.bean.PayOutMessage; import com.egzosn.pay.common.exception.PayErrorException; import com.egzosn.pay.wx.bean.WxPayMessage; import java.util.Map; /** * 微信支付回调处理器 * Created by ZaoSheng on 2016/6/1. */ public class WxPayMessageHandler implements PayMessageHandler { @Override public PayOutMessage handle(WxPayMessage payMessage, Map context, PayService payService) throws PayErrorException { //交易状态 if ("SUCCESS".equals(payMessage.getPayMessage().get("result_code"))){ /////这里进行成功的处理 return payService.getPayOutMessage("SUCCESS", "OK"); } return payService.getPayOutMessage("FAIL", "失败"); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/config/interceptor/AliPayMessageInterceptor.java ================================================ package com.egzosn.pay.spring.boot.demo.config.interceptor; import com.egzosn.pay.ali.api.AliPayService; import com.egzosn.pay.ali.bean.AliPayMessage; import com.egzosn.pay.common.api.PayMessageHandler; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.exception.PayErrorException; import org.springframework.stereotype.Component; import java.util.Map; /** * 支付宝回调信息拦截器 * @author: egan * email egzosn@gmail.com * date 2017/1/18 19:28 */ @Component public class AliPayMessageInterceptor implements PayMessageInterceptor { /** * 拦截支付消息 * * @param payMessage 支付回调消息 * @param context 上下文,如果handler或interceptor之间有信息要传递,可以用这个 * @param payService 支付服务 * @return true代表OK,false代表不OK并直接中断对应的支付处理器 * @see PayMessageHandler 支付处理器 * @throws PayErrorException PayErrorException* */ @Override public boolean intercept(AliPayMessage payMessage, Map context, AliPayService payService) throws PayErrorException { //这里进行拦截器处理,自行实现 String outTradeNo = payMessage.getOutTradeNo(); // 设置外部单号 // amtApplyService.fillApplyoutId(outTradeNo, (String) payMessage.getPayMessage().get("trade_no")); //获取账单 // AmtApply amtApply = amtApplyService.getAmtApplyByApplyId(outTradeNo); // if (null == amtApply){ // Log4jUtil.info("app 阿里pay:" + outTradeNo); // return false; // } // // 重复回调不进行处理 // if(amtApply.getApplyState().shortValue()== ApplyStateEnum.success.getCode()){ // return false; // } //将账单存储至上下文对象中 // context.put("amtApply", amtApply); return true; } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/java/com/egzosn/pay/spring/boot/demo/controller/PayMerchantController.java ================================================ package com.egzosn.pay.spring.boot.demo.controller; import java.io.IOException; import java.math.BigDecimal; import java.util.Map; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.egzosn.pay.common.api.PayMessageInterceptor; import com.egzosn.pay.common.bean.AssistOrder; import com.egzosn.pay.common.bean.RefundOrder; import com.egzosn.pay.common.bean.RefundResult; import com.egzosn.pay.common.bean.TransferOrder; import com.egzosn.pay.common.util.MapGen; import com.egzosn.pay.spring.boot.core.PayServiceManager; import com.egzosn.pay.spring.boot.core.bean.MerchantPayOrder; import com.egzosn.pay.spring.boot.core.bean.MerchantQueryOrder; import com.egzosn.pay.spring.boot.core.merchant.PaymentPlatformMerchantDetails; import com.egzosn.pay.spring.boot.core.provider.MerchantDetailsManager; import com.egzosn.pay.web.support.HttpRequestNoticeParams; /** * @author egan * email egzosn@gmail.com * date 2019/5/26.20:10 */ @RequestMapping("pay") @Controller public class PayMerchantController { @Autowired private PayServiceManager manager; @Autowired private MerchantDetailsManager merchantDetailsManager; @GetMapping("merchantExists") public Map merchantExists() { return new MapGen("exist", merchantDetailsManager.merchantExists("1")).getAttr(); } /** * 网页支付 * * @param detailsId 列表id * @param wayTrade 交易方式 * @return 网页 */ @ResponseBody @RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8") public String toPay(String detailsId, String wayTrade, BigDecimal price) { MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); return manager.toPay(payOrder); } /** * 公众号支付 * * @param detailsId 账户id * @param openid openid * @param price 金额 * @return 返回jsapi所需参数 */ @RequestMapping(value = "jsapi") public Map jsapi(String detailsId, String openid, BigDecimal price) { //获取对应的支付账户操作工具(可根据账户id) MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, "JSAPI", "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); payOrder.setOpenid(openid); return manager.getOrderInfo(payOrder); } /** * 获取支付预订单信息 * * @param detailsId 支付账户id * @param price 金额 * @return 支付预订单信息 */ @RequestMapping("app") public Map getOrderInfo(String detailsId, BigDecimal price) { //获取对应的支付账户操作工具(可根据账户id) MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, "APP", "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); return manager.app(payOrder); } /** * 二维码 * * @param detailsId 列表id * @param wayTrade 交易方式 * @return 二维码 */ @ResponseBody @RequestMapping(value = "toQrPay.jpg", produces = "image/jpeg;charset=UTF-8") public byte[] toQrPay(String detailsId, String wayTrade, BigDecimal price) throws IOException { MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); return manager.toQrPay(payOrder); } /** * 二维码信息 * * @param detailsId 列表id * @param wayTrade 交易方式 * @return 二维码信息 */ @ResponseBody @RequestMapping(value = "getQrPay.json") public String getQrPay(String detailsId, String wayTrade, BigDecimal price) { MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, wayTrade, "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); return manager.getQrPay(payOrder); } /** * 刷卡付,pos主动扫码付款(条码付) * * @param detailsId 账户id * @param transactionType 交易类型, 这个针对于每一个 支付类型的对应的几种交易方式 * @param authCode 授权码,条码等 * @param price 金额 * @return 支付结果 */ @RequestMapping(value = "microPay") public Map microPay(String detailsId, String transactionType, BigDecimal price, String authCode) { //获取对应的支付账户操作工具(可根据账户id) MerchantPayOrder payOrder = new MerchantPayOrder(detailsId, transactionType, "订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", "")); //设置授权码,条码等 payOrder.setAuthCode(authCode); return manager.microPay(payOrder); } /** * 支付回调地址 * * @param request 请求 * @param detailsId 列表id * @return 支付是否成功 * 拦截器相关增加, 详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} *

* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} */ @RequestMapping(value = "payBack/{deatilsId}.json") public String payBack(HttpServletRequest request, @PathVariable String detailsId) { //业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler() return manager.payBack(detailsId, new HttpRequestNoticeParams(request)); } /** * 支付回调地址 * * @param request 请求 * @param detailsId 列表id * @return 支付是否成功 * @throws IOException IOException * 拦截器相关增加, 详情查看{@link com.egzosn.pay.common.api.PayService#addPayMessageInterceptor(PayMessageInterceptor)} *

* 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} *

* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler} */ @Deprecated @RequestMapping(value = "payBackOld{detailsId}.json") public String payBackOld(HttpServletRequest request, @PathVariable String detailsId) throws IOException { //业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler() return manager.payBack(detailsId, request.getParameterMap(), request.getInputStream()); } /** * 查询 * 入参根据实际情况来填写, * 必填参数 detailsId * 普通查询 tradeNo,outTradeNo * 具体详情查看pay-java-demo内对应demo * * @param order 订单的请求体 * @return 返回查询回来的结果集,支付方原值返回 */ @RequestMapping("query") public Map query(MerchantQueryOrder order) { return manager.query(order); } /** * 交易关闭接口 * * @param detailsId id * @param tradeNo tradeNo * @param outTradeNo outTradeNo * @return 返回支付方交易关闭后的结果 */ @RequestMapping("close") public Map close(String detailsId, String tradeNo, String outTradeNo) { final MerchantQueryOrder order = new MerchantQueryOrder(); order.setDetailsId(detailsId); order.setTradeNo(tradeNo); order.setOutTradeNo(outTradeNo); return manager.close(order); } /** * 申请退款接口 * * @param detailsId 账户id * @param order 订单的请求体 * @return 返回支付方申请退款后的结果 */ @RequestMapping("refund") public RefundResult refund(String detailsId, RefundOrder order) { return manager.refund(detailsId, order); } /** * 查询退款 * * @param order 订单的请求体 * @return 返回支付方查询退款后的结果 */ @RequestMapping("refundquery") public Map refundQuery(String detailsId, RefundOrder order) { return manager.refundQuery(detailsId, order); } /** * 下载对账单 * 必填参数 detailsId * 普通查询 billDate, billType * 具体详情查看pay-java-demo内对应demo * * @param order 订单的请求体 * @return 返回支付方下载对账单的结果 */ @RequestMapping("downloadBill") public Object downloadBill(MerchantQueryOrder order) { return manager.downloadBill(order); } /** * 转账 * * @param order 转账订单 * @return 对应的转账结果 * 具体参数看具体支付平台,案例pay-java-parent/pay-java-demo/com.egzosn.pay.demo.controller */ @RequestMapping("transfer/{detailsId}") public Map transfer(@PathVariable String detailsId, TransferOrder order) { return manager.transfer(detailsId, order); } /** * 转账 * * @param order 转账订单 * @return 对应的转账结果 * 具体参数看具体支付平台, */ @RequestMapping("transferQuery/{detailsId}") public Map transferQuery(@PathVariable String detailsId, AssistOrder order) { return manager.transferQuery(detailsId, order); } } ================================================ FILE: pay-spring-boot-starter-demo/src/main/resources/ali/alipayCertPublicKey_RSA2.crt ================================================ -----BEGIN CERTIFICATE----- MIIDqDCCApCgAwIBAgIQIBkQFQ/dyVOPUjiooDnPNjANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMTkxMDE1MTMzMjEzWhcNMjIxMDEzMTMzMjEzWjB6 MQswCQYDVQQGEwJDTjEVMBMGA1UECgwM5rKZ566x546v5aKDMQ8wDQYDVQQLDAZBbGlwYXkxQzBB BgNVBAMMOuaUr+S7mOWunSjkuK3lm70p572R57uc5oqA5pyv5pyJ6ZmQ5YWs5Y+4LTIwODgxMDIx Njk5MTY0MzYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0iWE/WO7qDt8whynlxH6/ tuTtFQj6KtHcdSbR6ff0r9ScYHIC6UYUtlT3/8jAi7fEJN8aREdZXy/2IwmE2bFapvHB6FuVMKXh /i4QPP2cQJzVDM56wY/HqcyxsDHz7eP9nanU4KT4azOz+dQESNVj+Xw05CgTmQQ3JaXRYFMU8841 abxXTZg7x03HS7b16CHR2TXs55L6LkbQX45jvFad+NKs6o9gC2ij1xwRBQhuGJbPlfdOqaTOM0vc miOy+vKYvKb3vPQI5h+XVGU/y2piE0oszQWZWd1F9w70eBPHWY7i2PaGwNk38CcBve9QtoyURLEi D6LrJQGkQ6LCP7MtAgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQsFAAOCAQEA j6xIDkX/GbcQoeMTrJIP2sI4AsStxwG5QjYh021hA74agx0XGQyWrRhXtKpIyEfNxwSZaWgoJqZ3 uBGTMfiVxjoI1xvHrv5kLQAU8lAt3thdwMYkwP56u51jT15V56OzwvWycGplEwGBw/ln6nc6lwcA FTPnBR82Wv0J3+B6iSyw/bqXAiWM9ftIv9ex10YIjBRGC0kK0OFS2h1Cq/lEuFSW59cbo5h901Jx yPVVa6qPYdkLatI/Cxexan+oKJG1BpUoRsKx95wPPV/jxtjP/b8i4qvq71V/h35LaX0uMkgVMJj0 7SFBl8ciLbSrWZfmMt/sXQszNIhXU/hZwslNQA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIE4jCCAsqgAwIBAgIIddq/0OOwJzIwDQYJKoZIhvcNAQELBQAwejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMjE0MzAzMVoXDTM3MTEyNjE0MzAzMVowgYIxCzAJBgNVBAYTAkNOMRYwFAYDVQQKDA1BbnQgRmluYW5jaWFsMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE5MDcGA1UEAwwwQW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDbGFzcyAxIFIxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3OruCD7d4evJiEKxzJQYmwp5ziF7lT4fMpBb+WLme42Ulrkh4cJCDEOTUL29Yb8NyQ6cRe9UHLupI2HbByDZoSJl7nkxyi5NGJLaADC7wnFBJq39WMaVBzouFo0yQkkYNbbkJm+MsV4obu3l2xFGQx72bz6ThDJLpfYJbnGXqC4Bcyn8ubj1ddrJ0VsGdj/3Knmuo7XWLYqqN/qomK3LJIpfhVozi0b2FWQl+lE9urch+FVhXSg0AlRGn8FTOVNlKrY+hAKZGZhqC+J+BD4GL3hQZzVeNl0tMmSGz474lnt7DExNq33WfyJkn5UIoCfg8Tno7XTnocmBzbNYPq1aSQIDAQABo2MwYTAfBgNVHSMEGDAWgBRfdLQEwE8HWurlsdsio4dBspzhATAdBgNVHQ4EFgQUcQfiBGEW5OXyZesxD8ng9Dya1ZEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAGkc6bDB4YQCa5D6IbgRtLfiqTQb5DeCp38uVKKrUl8ZCE5U+wXSu/fFhOkIs+Aq9tEOdPWgi7TAxPMMbfJRTAF20qK1qF/X6lwRYGSi7LBbEhmI7dYFKj7i7z6fupBMVaI4C4O8KJGfovp3qD/FkXyb13Lo8vL85Ll0BFk89Qbim0qYhW2JRsf9G46vBeIZaoMm8iMv9vvlVgMs30R96W+gZBgvlIE4ah+oOEUd+G/V74vTbaXtWI8gkmwCzs/yUGW2g2ERHqZ3ksq4xwL+mNmqRNzq3aC9iA4p0uoHp/els89vWHCUaPjHmEnhx+M843/WVjN8LWpoeQ+wc7Wz1jfYy0e+JXidqWkPn7qorlEQTfzcFBZh+YHnV6oVtcG5iYatRKVTAPA+RrjJnEEzn6hAIPsiYsLmdA18f6ruuUUuKRukAEbCQ9q9L1gyOkaz2LxZj5kOFyemDa3pjqESuHuazztnOvs6u4YrH03CPyK3G/6MhCNEJTxGDYy+8bRtNsTGRUbdmhZm/u8tjYIreNEy55f4WYlb72R6PODBLXmf4HWWPpyX1Zy9TEhmFsuPfelhBrdmBVM1iTwVFLW7gLqoEwzYhMt5KRPjmfCc2P2pcbpLnYNcbSYiykFsCa7jHG0137Jv8Z/QH2N9r4+xdER7SW40ndmD59ynmGvrWUMj -----END CERTIFICATE----- ================================================ FILE: pay-spring-boot-starter-demo/src/main/resources/ali/alipayRootCert.crt ================================================ -----BEGIN CERTIFICATE----- MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b 53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI pDoiVhsLwg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0 MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2 xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6 vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1 Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98 SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe 9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90 tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3 IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW 05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41 T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N 1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02 77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi kT9qhqn+lw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0 WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ 4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2 zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5 4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3 U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU 1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX Yf4Zr0fJsGuv -----END CERTIFICATE----- ================================================ FILE: pay-spring-boot-starter-demo/src/main/resources/ali/appCertPublicKey_2016080400165436.crt ================================================ -----BEGIN CERTIFICATE----- MIIDjzCCAnegAwIBAgIQICARMFLSkg9etOjTIGp0hjANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMjAxMTMwMDMwMzAyWhcNMjMxMTI5MDMwMzAyWjBh MQswCQYDVQQGEwJDTjEVMBMGA1UECgwM5rKZ566x546v5aKDMQ8wDQYDVQQLDAZBbGlwYXkxKjAo BgNVBAMMITIwODgxMDIxNjk5MTY0MzYtMjAxNjA4MDQwMDE2NTQzNjCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBALDswPYLC/+OdeywWNecbHcmUYXnuAlrZphslFXwyc2I9Wlfgdr7xmOd AOG+StYfiEebNy6M6vbXceqWgylRJgHMI+JcZVFRS92KZ6NwcdOh3ucjiDqfO3PN97L9Nc0Meanu 9jek4hyMHRmfSmQ0DPa0oAWSpvitoc6pMHRADTMPbgKf7bonZQnJhFyB4fQa1JC5SubvJoay4pqS H6q2BYXpHvWfk8wY5NDksfeLRZUd8IGQ0aAkLrIL3odHgPtyiyjIoPT6WnxQH81VRaXtO38os6AV TCHQYpJgV+/no79UFXb7GoIYTg+VkRJ9W46rPm+OPHPDfEMBQmtXyFJf8AkCAwEAAaMSMBAwDgYD VR0PAQH/BAQDAgTwMA0GCSqGSIb3DQEBCwUAA4IBAQChVg6GZf8LcjlMlIt7RhQZjbycGlRB5pp2 bckojulTEoHbmjvjL9LRJAtjuHQ1Teuy3meK6iT/J+O8PWXEigLtX+K+5Xne3JpRcztAciRmWhLe dAEvh1aPPmiG11ZDPC2dDOtTQVIleLpbFtYkqn9IVsU2n+2lmM7aMbw1969wADE4mov2X3m6bnuI CzrPGpWiI0MwLp00e0sNHnHXpzENxtabBqabYvL/AH7QZgAmX0JTxYwx0zW7r1JiAc+42Eh/qwqE TJa+tOY+Iig5GcFkc6fE7guTNGxz2OhKr2whNq6uRnLbA+Xwx11NhE1K3NHNrZZpSf3QW1//xJoC zlBJ -----END CERTIFICATE----- ================================================ FILE: pay-spring-boot-starter-demo/src/main/resources/ali/www.egzosn.com_私钥.txt ================================================ MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCw7MD2Cwv/jnXssFjXnGx3JlGF57gJa2aYbJRV8MnNiPVpX4Ha+8ZjnQDhvkrWH4hHmzcujOr213HqloMpUSYBzCPiXGVRUUvdimejcHHTod7nI4g6nztzzfey/TXNDHmp7vY3pOIcjB0Zn0pkNAz2tKAFkqb4raHOqTB0QA0zD24Cn+26J2UJyYRcgeH0GtSQuUrm7yaGsuKakh+qtgWF6R71n5PMGOTQ5LH3i0WVHfCBkNGgJC6yC96HR4D7cosoyKD0+lp8UB/NVUWl7Tt/KLOgFUwh0GKSYFfv56O/VBV2+xqCGE4PlZESfVuOqz5vjjxzw3xDAUJrV8hSX/AJAgMBAAECggEBAKE0d3U4B4yo/2XUIH8EdgfykCFUSum6RFbpyBauORHfksyaSzV+ZvtomN8XhhSn0oJ8OMFfgM+86nz2+zdwSxMkMCYWTfLUAi4v59KRqAVO3kz4oS3Y3FDeAK3D7XuRvGFL7GgzAhtEx1cLPrsiehVn6s5pG15GxsIIgq/JlL1J88wn1zENLrVHmD6z/JpXvfb/RS1yR+5lyoohp4g0Ph9jJ3bCyUbRpK0QkPEzgAuWL0K2ITCL7PYHNAplI8d2xHHOLF9Qdjyx+ZrQ/RxtqzfyWzhqjsmp2qlgNCxWlt3woS9UhDB+nRvjEoWTJmIOszAMYuj8wGlX+3Ui3ALOdQECgYEA25EqnFPFinUnzgNvB6NYmh5STmZun6s4bUOLqwefKtEvrOtRwTu7sB7NIf37fizG3/MJUWHxiLy2/3ub4d2JxdDNBtJoEqnp6QB12qglCNa4CajdjtJa1dR81F9QvytsqEkmPYXFPPyviB0FcSIDAGMb3IbwvIfzBPY9WY8dJnECgYEAzkg3yKEFBZ8BU0WQ+3hyfKUoAhBEnxouxRSTBcXxwstJRiqaGTVe5aoJGQI+0xS7Z6q07XDtN2t97s6DnRLWbljsX6B64itzNhXRyzjdD3iZDU/KSw7khjhXf8XOZaj9eXmACDiUnkEn1xsM8bLiRGqB8y5f3aMY/RpuACGXnxkCgYEAx/zwT9Vpr1RIfjfYcJ+Su0X0994K0roUukj0tUJK8qf4gcsQ+y1aJe/YLib1ZBaKyj7G9O5+HmqtUAUZld/AdoJZzOXmz2EeYhD+R7wxh1xz4rCBpW3qOKvDS3jJxmZaIOoHv6/RWFxb0WGFrGcrTrX3EaWDLmWxr4pNlP5qsbECgYATllntrBR8/ycyEAX/SuWcHlaZM5BAh0zvm8+GGdCmDYWMqxjs0duL9URd4o+ynWJaKqR5c2KjA4r2tRdcP+Cqo7j2L5fbiAKtnQ7JvEGJaYsm72+nBuf+MrVkRZUepBhFg5r7rNu31zoAO+pTvQetNWvXeozRz93ckrjlPEtYaQKBgQDFwbV92rlRMLjZzlY+o0knoeJBjPQmPdiBTpGNimdy9L4c2Ure7affjcUiYhkKqrK5k5SScJTATgyQ7JF346FdtUtZ/6Kkj1RwJmmprPrDa9CATLoTle7g9OVd4sHT2ITHZMzPaF3ILvzcwJ70AD1xcxCQb+/7sDPmw7Mc8gOA7Q== ================================================ FILE: pay-spring-boot-starter-demo/src/main/resources/application.yml ================================================ server: port: 8080 # context-path: /dock logging: level: # root: debug com: egzosn: debug file: examples.log spring: datasource: #数据库文件存放 /doc/sql目录下 url: jdbc:mysql://localhost:3306/merchant_pay?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&useOldAliasMetadataBehavior=true&serverTimezone=UTC username: root password: root max-active: 20 max-idle: 8 min-idle: 8 initial-size: 10 #指定连接多久没被使用时,被设置为空闲,默认为10ms idle-timeout: 10 driver-class-name: com.mysql.cj.jdbc.Driver #验证连接的有效性 test-while-idle: true validation-query: select 1 from dual #空闲连接回收的时间间隔,与test-while-idle一起使用,设置5分钟 time-between-eviction-runs-millis: 300000 #连接池空闲连接的有效时间 ,设置30分钟 min-evictable-idle-time-millis: 1800000 ================================================ FILE: pom.xml ================================================ pay-java-parent com.egzosn 2.14.9 4.0.0 pay-spring-boot-starter-parent pay-spring-boot-starter-parent pom 1.0.5 pay-spring-boot pay-spring-boot-starter pay-spring-boot-autoconfigue pay-spring-boot-starter-demo 17 2.14.9 The Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt Egan egzosn@gmail.com https://github.com/egzosn scm:git:https://github.com/egzosn/pay-java-parent.git scm:git:git@github.com:egzosn/pay-java-parent.git https://github.com/egzosn/pay-java-parent org.springframework.boot spring-boot-autoconfigure com.egzosn pay-java-common true com.egzosn pay-java-ali true com.egzosn pay-java-wx true com.egzosn pay-java-wx-youdian true com.egzosn pay-java-union true com.egzosn pay-java-payoneer true com.egzosn pay-java-paypal true com.egzosn pay-java-fuiou true org.springframework spring-jdbc true org.springframework.boot spring-boot-dependencies 2.4.0 pom import com.egzosn pay-java-common ${pay.version} com.egzosn pay-java-ali ${pay.version} com.egzosn pay-java-wx ${pay.version} com.egzosn pay-java-web-support ${pay.version} com.egzosn pay-java-wx-youdian ${pay.version} com.egzosn pay-java-union ${pay.version} com.egzosn pay-java-payoneer ${pay.version} com.egzosn pay-java-paypal ${pay.version} com.egzosn pay-java-fuiou ${pay.version} org.apache.maven.plugins maven-compiler-plugin -parameters ${maven.compiler.source} ${maven.compiler.target} ${project.build.sourceEncoding} org.codehaus.mojo flatten-maven-plugin ${flatten-maven-plugin.version} true resolveCiFriendliesOnly flatten process-resources flatten flatten.clean clean clean local true proc org.apache.maven.plugins maven-source-plugin 3.3.0 attach-sources jar-no-fork org.apache.maven.plugins maven-javadoc-plugin 3.6.0 attach-javadocs jar org.apache.maven.plugins maven-gpg-plugin 1.6 sign-artifacts verify sign org.sonatype.central central-publishing-maven-plugin 0.5.0 true central