最近公司要作一個有關支付的相關項目,須要對接支付寶的支付接口,實現掃描二維碼支付功能,爲此研究了一下支付寶相關業務。主要依據就是支付寶的相關接口文檔:html
https://docs.open.alipay.com/catalog,重點關注以下紅色方框部分前端
先看一下支付寶掃描二維碼支付的業務流程,直接摘出來以下:java
掃碼支付,指用戶打開支付寶錢包中的「掃一掃」功能,掃描商家展現在某收銀場景下的二維碼並進行支付的模式。該模式適用於線下實體店支付、面對面支付等場景。web
業務流程:spring
使用步驟:express
產品特色:apache
基本上咱們開發經常使用的也就是一個生成二維碼的預建立訂單接口,一個取消,一個退款,一個支付成功後的回調接口json
接下來,咱們開始準備環境進行開發,不論是運行官方的demo仍是集成到項目中,咱們都須要進行相應的環境準備,目前,網上的沙箱環境比較多,我就直接配置我的商家的真實環境來記錄博客,沙箱環境本博主在公司裏面搭建過,今天在家就用本身支付寶開發商家環境,更爲真實的記錄這個過程。api
其實支付寶這塊的api開發接口文檔等仍是寫的比較明白的,若是真的是有搞不定的地方也是能夠在線詢問支付寶技術客服的,並且回覆的速度也是挺快。如今支付寶的驗籤功能已經封裝了,不須要咱們在本身實現驗籤功能。挺方便springboot
配置環境咱們直接點擊上面的鏈接接入指引按照步驟進行:
1、建立應用
建立完成就分配了appid,
紅框設置步驟以下:
設置應用公鑰
保存以後生成支付寶公鑰
上述所有設置完成之後提交審覈
接下來等待審覈經過便可,
DEMO運行
下載demo地址-------> https://docs.open.alipay.com/194/105201/
解壓後而後導入普通工程
導入後目錄結構以下
而後根據demo進行
# 直接運行demo步驟以下(eclipse直接導入工程便可):
一、請先確認zfbinfo.properties配置文件是否已配置完成
二、運行Main.java中的main方法
咱們主要修改的是zfbinfo.properties文件配置私鑰,支付寶公鑰,pid,appid等信息便可運行
1 # 支付寶網關名、partnerId和appId #注意區分沙箱環境和在線環境 2 open_api_domain = https://openapi.alipay.com/gateway.do(要填寫) 3 mcloud_api_domain = http://mcloudmonitor.com/gateway.do 4 pid = 此處請填寫你的PID 5 appid = 此處請填寫你當面付的APPID 6 7 # RSA私鑰、公鑰和支付寶公鑰 8 private_key = 此處請填寫你的商戶私鑰且轉PKCS8格式(要填寫) 9 public_key = 此處請填寫你的商戶公鑰(要填寫) 10 11 #SHA1withRsa對應支付寶公鑰(這是非java的形式要填寫) 12 #alipay_public_key = 13 14 #SHA256withRsa對應支付寶公鑰(java要填寫) 15 alipay_public_key = 16 17 # 簽名類型: RSA->SHA1withRsa,RSA2->SHA256withRsa 18 sign_type = RSA2 19 # 當面付最大查詢次數和查詢間隔(毫秒) 20 max_query_retry = 5 21 query_duration = 5000 22 23 # 當面付最大撤銷次數和撤銷間隔(毫秒) 24 max_cancel_retry = 3 25 cancel_duration = 2000 26 27 # 交易保障線程第一次調度延遲和調度間隔(秒) 28 heartbeat_delay = 5 29 heartbeat_duration = 900
只要填寫正確就能夠直接經過main方法測試運行。
接下來咱們看看怎麼集成到咱們本身的項目中,做爲一個接口提供出去給前端或者app調用,這個其實demo裏面readme也說的很清楚,先把readme整個貼出來
DEMO裏的readme
1 # DEMO僅供參考,實際開發中須要結合具體業務場景修改使用 2 # 3 # 運行環境:jdk1.6及以上 4 # 當面付2.0demo使用前必讀 5 6 # 直接運行demo步驟以下(eclipse直接導入工程便可): 7 一、請先確認zfbinfo.properties配置文件是否已配置完成 8 二、運行Main.java中的main方法 9 10 # 集成至商戶系統步驟以下(以maven工程結構爲例): 11 一、拷貝java目錄下的Main.java(和DemoHbRunner.java,若是須要集成交易保障接口)至系統商源代碼目錄 12 二、將lib目錄下全部jar文件添加至系統商lib目錄,若是沒有alipay-trade-sdk.jar(此jar包集成了當面付交易邏輯和交易保障接口),則將TradePaySDK編譯爲該jar包 13 三、拷貝resources目錄下的配置文件至系統商classpath根目錄 14 四、在系統商項目中運行Main方法,確認集成無誤 15 五、系統商使用main方法中的調用樣例進行商戶端系統開發 16 17 Q:掃碼支付、統一下單+JSAPI喚起收銀臺支付後,支付成功異步通知如何處理? 18 一、商戶須要驗證該通知數據中的out_trade_no是否爲商戶系統中建立的訂單號 19 二、判斷total_amount是否確實爲該訂單的實際金額(即商戶訂單建立時的金額) 20 三、校驗通知中的seller_id(或者seller_email) 是否爲該筆交易對應的操做方(一個商戶可能有多個seller_id/seller_email) 21 四、驗證接口調用方的app_id。。 22 23 # 交易保障接口常見問題 24 https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.yzagzo&treeId=26&articleId=103903&docType=1 25 26 ### 當面付2.0demo代碼結構TradePayDemo ### 27 src 28 └── main 29 ├── java 30 │ └── com 31 │ └── alipay 32 │ └── demo 33 │ └── trade 34 │ ├── DemoHbRunner.java # 交易保障數據收集器的範例實現,若是接入交易保障接口,參考此類實現,調用參考Main方法 35 │ └── Main.java ######## 當面付2.0調用範例 ######## 36 ├── resources 37 │ └── zfbinfo.properties # 配置文件,調用Main方法以前請確認配置文件是否已正確配置 38 └── webapp 39 ├── WEB-INF 40 │ ├── lib # 依賴類庫 41 │ │ ├── alipay-sdk-java20151021120052-source.jar 42 │ │ ├── alipay-sdk-java20151021120052.jar 43 │ │ ├── commons-codec-1.10.jar 44 │ │ ├── alipay-trade-sdk.jar # TradePaySDK模塊建立生成的lib 45 │ │ ├── commons-configuration-1.10.jar 46 │ │ ├── commons-lang-2.6.jar 47 │ │ ├── commons-logging-1.1.1.jar 48 │ │ ├── core-2.1.jar 49 │ │ ├── gson-2.3.1.jar 50 │ │ └── hamcrest-core-1.3.jar 51 │ └── web.xml 52 ├── images 53 │ ├── alipay.gif 54 │ └── new-btn-fixed.png 55 ├── index.html # web方式調用當面付的首頁 56 ├── trade_pay.jsp # 當面付2.0條碼支付web界面,本質和Main方法中條碼支付方法一致 57 ├── trade_precreate.jsp # 當面付2.0預下單web界面,本質和Main方法中預下單方法一致 58 ├── trade_query.jsp # 當面付2.0查詢web界面,本質和Main方法中查詢方法一致 59 └── trade_refund.jsp # 當面付2.0退貨界面,本質和Main方法中退貨方法一致 60 61 ### 當面付2.0sdk代碼結構TradePaySDK ### 62 src 63 └── main 64 ├── java 65 │ └── com 66 │ └── alipay 67 │ └── demo 68 │ └── trade 69 │ ├── config 70 │ │ ├── Configs.java # 配置文件,解析properties文件 71 │ │ └── Constants.java # 常量定義 72 │ ├── model 73 │ │ ├── ExtendParams.java # 擴展參數 74 │ │ ├── GoodsDetail.java 75 │ │ ├── TradeStatus.java 76 │ │ ├── builder # 當面付2.0請求包 77 │ │ │ ├── AlipayHeartbeatSynContentBuilder.java # 服務保障接口請求bizContent結構體 78 │ │ │ ├── AlipayTradePayContentBuilder.java # 條碼支付請求bizContent結構體 79 │ │ │ ├── AlipayTradePrecreateContentBuilder.java # 掃碼支付(產生二維碼)請求bizContent結構體 80 │ │ │ ├── AlipayTradeQueryCententBuilder.java # 當面付2.0查詢請求bizContent結構體 81 │ │ │ ├── AlipayTradeRefundContentBuilder.java # 當面付2.0退款請求bizContent結構體 82 │ │ │ └── RequestBuilder.java # 請求抽象類 83 │ │ ├── hb # 服務保障接口數據模型 84 │ │ │ ├── EquipStatus.java # 發送心跳時的設備狀態枚舉 85 │ │ │ ├── EquipStatusAdapter.java 86 │ │ │ ├── ExceptionInfo.java # 異常信息枚舉 87 │ │ │ ├── ExceptionInfoAdapter.java 88 │ │ │ ├── HbStatus.java # 交易狀態 89 │ │ │ ├── PosTradeInfo.java # 機具商同步使用的交易結構體 90 │ │ │ ├── Product.java # 發送心跳的設備所依賴的支付寶產品 91 │ │ │ ├── SysTradeInfo.java # 系統商同步使用的交易結構體 92 │ │ │ ├── TradeInfo.java # 交易結構體接口,用於隱藏系統商交易結構體和機具商交易結構體的不一樣 93 │ │ │ ├── TradeInfoAdapter.java 94 │ │ │ └── Type.java # 發送心跳的設備類型枚舉 95 │ │ └── result 當面付2.0應答包 96 │ │ ├── AlipayF2FPayResult.java # 當面付2.0支付應答 97 │ │ ├── AlipayF2FPrecreateResult.java # 當面付2.0預下單(產生二維碼)應答 98 │ │ ├── AlipayF2FQueryResult.java # 當面付2.0查詢應答 99 │ │ ├── AlipayF2FRefundResult.java # 當面付2.0退貨應答 100 │ │ └── Result.java 101 │ ├── service 102 │ │ ├── AlipayMonitorService.java # 提供交易保障服務 103 │ │ ├── AlipayTradeService.java # 提供當面付2.0服務 104 │ │ └── impl 105 │ │ ├── AbsAlipayService.java # 服務實現類抽象類,全部的服務實現類的父類 106 │ │ ├── AbsAlipayTradeService.java # 當面付服務實現類抽象類,包含了當面付2.0預下單、查詢、退貨交易的封裝 107 │ │ ├── AlipayMonitorServiceImpl.java # 交易保障服務具體實現 108 │ │ ├── AlipayTradeServiceImpl.java # 當面付2.0具體實現(不提供交易保障接口的集成) 109 │ │ ├── AlipayTradeWithHBServiceImpl.java # 當面付2.0具體實現(集成了交易保障邏輯) 110 │ │ └── hb # 交易保障邏輯相關代碼 111 │ │ ├── AbsHbRunner.java # 抽象的交易保障數據收集器,系統商建立本身的子類用於自定義收集數據,參考DemoHbRunner 112 │ │ ├── HbListener.java # 交易保障監聽器實現,每當交易完成後,將交易耗時寫入隊列 113 │ │ ├── HbQueue.java # 保存交易數據的隊列,添加隊列每次只加入1條交易,讀取隊列每次儘可能讀滿30條交易 114 │ │ └── TradeListener.java # 交易監聽接口,在當面付交易流程中加入監聽邏輯 115 │ └── utils 116 │ ├── GsonFactory.java # 使用了gson序列化 117 │ ├── Utils.java # 雜物工具類 118 │ └── ZxingUtils.java # 使用了zxing庫進行二維碼的生成 119 └── lib # 依賴類庫 120 ├── alipay-sdk-java20151021120052-source.jar # 支付寶底層api調用的sdk源碼 121 ├── alipay-sdk-java20151021120052.jar 122 ├── commons-codec-1.10.jar 123 ├── commons-configuration-1.10.jar 124 ├── commons-lang-2.6.jar 125 ├── commons-logging-1.1.1.jar 126 ├── core-2.1.jar 127 ├── gson-2.3.1.jar 128 └── hamcrest-core-1.3.jar 129 130 # DEMO僅供參考,實際開發中須要結合具體業務場景修改使用
重點是:
# 集成至商戶系統步驟以下(以maven工程結構爲例):
一、拷貝java目錄下的Main.java(和DemoHbRunner.java,若是須要集成交易保障接口)至系統商源代碼目錄
二、將lib目錄下全部jar文件添加至系統商lib目錄,若是沒有alipay-trade-sdk.jar(此jar包集成了當面付交易邏輯和交易保障接口),則將TradePaySDK編譯爲該jar包
三、拷貝resources目錄下的配置文件至系統商classpath根目錄
四、在系統商項目中運行Main方法,確認集成無誤
五、系統商使用main方法中的調用樣例進行商戶端系統開發
Q:掃碼支付、統一下單+JSAPI喚起收銀臺支付後,支付成功異步通知如何處理?
一、商戶須要驗證該通知數據中的out_trade_no是否爲商戶系統中建立的訂單號
二、判斷total_amount是否確實爲該訂單的實際金額(即商戶訂單建立時的金額)
三、校驗通知中的seller_id(或者seller_email) 是否爲該筆交易對應的操做方(一個商戶可能有多個seller_id/seller_email)
四、驗證接口調用方的app_id。。
這裏咱們其實只須要alipay-sdk-java-3.3.0.jar個及相關的commons-logging-1.1.1.jar,生成二維碼須要的包core-2.1.jar便可。而後新建springboot的maven項目
接下來就是你們都知道的
1.添加jar包
2.配置屬性文件
3.編寫支付相關代碼(這個能夠直接去官網拷貝便可https://docs.open.alipay.com/194/105203/,都有示例,拷貝後修改一下便可)
上代碼
新建springboot項目,項目結構以下圖:
pom
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 <parent> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-starter-parent</artifactId> 8 <version>2.0.5.RELEASE</version> 9 <relativePath/> <!-- lookup parent from repository --> 10 </parent> 11 <groupId>com.sharp</groupId> 12 <artifactId>alipay</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <name>alipay</name> 15 <description>Demo project for Spring Boot</description> 16 17 <properties> 18 <java.version>1.8</java.version> 19 </properties> 20 21 <dependencies> 22 <dependency> 23 <groupId>org.springframework.boot</groupId> 24 <artifactId>spring-boot-starter-web</artifactId> 25 </dependency> 26 27 <dependency> 28 <groupId>org.springframework.boot</groupId> 29 <artifactId>spring-boot-starter-test</artifactId> 30 <scope>test</scope> 31 </dependency> 32 <!-- 支付接口配置 --> 33 <dependency> 34 <groupId>com.alipay.sdk</groupId> 35 <artifactId>alipay-sdk-java</artifactId> 36 <version>3.4.49.ALL</version> 37 </dependency> 38 <!-- 支付接口須要依賴commons-logging:jar:1.1.1 --> 39 <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --> 40 <dependency> 41 <groupId>commons-logging</groupId> 42 <artifactId>commons-logging</artifactId> 43 <version>1.1.1</version> 44 </dependency> 45 <!-- 生成支付二維碼須要jar --> 46 <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> 47 <dependency> 48 <groupId>com.google.zxing</groupId> 49 <artifactId>core</artifactId> 50 <version>3.3.3</version> 51 </dependency> 52 53 </dependencies> 54 55 <build> 56 <plugins> 57 <plugin> 58 <groupId>org.springframework.boot</groupId> 59 <artifactId>spring-boot-maven-plugin</artifactId> 60 </plugin> 61 </plugins> 62 </build> 63 64 </project>
zfbinfo屬性文件
1 # 支付寶網關名、partnerId和appId 2 open_api_domain=https://openapi.alipaydev.com/gateway.do 3 mcloud_api_domain = http://mcloudmonitor.com/gateway.do 4 pid = ¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 5 appid = ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ 6 7 # RSA私鑰、公鑰和支付寶公鑰 8 private_key = &&&&&&&&&&&&&&& 9 public_key = *************************** 10 #SHA1withRsa對應支付寶公鑰 11 #alipay_public_key = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB 12 13 #SHA256withRsa對應支付寶公鑰 14 alipay_public_key = ******* 15 16 # 簽名類型: RSA->SHA1withRsa,RSA2->SHA256withRsa 17 sign_type = RSA2 18 # 當面付最大查詢次數和查詢間隔(毫秒) 19 max_query_retry = 5 20 query_duration = 5000 21 22 # 當面付最大撤銷次數和撤銷間隔(毫秒) 23 max_cancel_retry = 3 24 cancel_duration = 2000 25 26 # 交易保障線程第一次調度延遲和調度間隔(秒) 27 heartbeat_delay = 5 28 heartbeat_duration = 900
config類初始化zfbinfo的屬性文件
1 /** 2 * 3 */ 4 package com.sharp.alipay.config; 5 6 import org.springframework.beans.factory.annotation.Value; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.ImportResource; 9 10 /** 11 * @Title zfbConfig.java 12 * @author 醉逍遙 13 * @date 2018年12月15日 14 * @version 1.0 15 */ 16 @Configuration 17 @ImportResource(value="classpath:zfbinfo.properties") 18 public class zfbConfig { 19 // 如下配置能夠寫死,也可從屬性文件中取出都可 20 // # 支付寶網關名、partnerId和appId 21 @Value("${open_api_domain}") 22 private static final String open_api_domain="https://openapi.alipaydev.com/gateway.do"; 23 // private static final String mcloud_api_domain = "http://mcloudmonitor.com/gateway.do"; 24 private static final String pid = "*****************"; 25 private static final String appid = "*****************"; 26 27 // # RSA私鑰、公鑰和支付寶公鑰 28 private static final String private_key = "***************************************"; 29 private static final String public_key = "*********************"; 30 // #SHA1withRsa對應支付寶公鑰 31 // #alipay_public_key = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB 32 33 // #SHA256withRsa對應支付寶公鑰 34 private static final String alipay_public_key = "*****************"; 35 36 // # 簽名類型: RSA->SHA1withRsa,RSA2->SHA256withRsa 37 private static final String sign_type = "RSA2"; 38 // ********************************************如下不用暫時註釋掉********************************************* 39 // # 當面付最大查詢次數和查詢間隔(毫秒) 40 /*max_query_retry = 5 41 query_duration = 5000 42 43 # 當面付最大撤銷次數和撤銷間隔(毫秒) 44 max_cancel_retry = 3 45 cancel_duration = 2000 46 47 # 交易保障線程第一次調度延遲和調度間隔(秒) 48 heartbeat_delay = 5 49 heartbeat_duration = 900*/ 50 51 }
controller均是支付寶api示例修改便可
1 /** 2 * 3 */ 4 package com.sharp.alipay.controller; 5 6 import javax.servlet.http.HttpServletRequest; 7 8 import org.springframework.web.bind.annotation.PostMapping; 9 import org.springframework.web.bind.annotation.RequestMapping; 10 import org.springframework.web.bind.annotation.RestController; 11 12 import com.alipay.api.AlipayApiException; 13 import com.alipay.api.AlipayClient; 14 import com.alipay.api.DefaultAlipayClient; 15 import com.alipay.api.request.AlipayTradeCancelRequest; 16 import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest; 17 import com.alipay.api.request.AlipayTradePrecreateRequest; 18 import com.alipay.api.request.AlipayTradeQueryRequest; 19 import com.alipay.api.request.AlipayTradeRefundRequest; 20 import com.alipay.api.response.AlipayTradeCancelResponse; 21 import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse; 22 import com.alipay.api.response.AlipayTradePrecreateResponse; 23 import com.alipay.api.response.AlipayTradeQueryResponse; 24 import com.alipay.api.response.AlipayTradeRefundResponse; 25 import com.sharp.alipay.util.ZxingUtils; 26 27 /** 28 * @Title AlipayController.java 29 * @author 醉逍遙 30 * @date 2018年12月15日 31 * @version 1.0 32 */ 33 @RestController 34 @RequestMapping("/alipay") 35 public class AlipayController { 36 @PostMapping("precreate") 37 public String precreate() { 38 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); 39 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); 40 // 設置支付成功後的回調地址,改地址必須外網能夠訪問到才行,因此調試該步驟必需要在外網環境,不然會出現支付成功可是卻不能回調 41 request.setNotifyUrl("最下面一個方法notify_url的含域名的絕對路徑,外網必定要能夠訪問哦"); 42 request.setBizContent("{" + 43 "\"out_trade_no\":\"20150320010101001\"," + 44 "\"seller_id\":\"2088102146225135\"," + 45 "\"total_amount\":88.88," + 46 "\"discountable_amount\":8.88," + 47 "\"subject\":\"Iphone6 16G\"," + 48 " \"goods_detail\":[{" + 49 " \"goods_id\":\"apple-01\"," + 50 "\"goods_name\":\"ipad\"," + 51 "\"quantity\":1," + 52 "\"price\":2000," + 53 "\"goods_category\":\"34543238\"," + 54 "\"categories_tree\":\"124868003|126232002|126252004\"," + 55 "\"body\":\"特價手機\"," + 56 "\"show_url\":\"http://www.alipay.com/xxx.jpg\"" + 57 " }]," + 58 "\"body\":\"Iphone6 16G\"," + 59 "\"operator_id\":\"yx_001\"," + 60 "\"store_id\":\"NJ_001\"," + 61 "\"disable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," + 62 "\"enable_pay_channels\":\"pcredit,moneyFund,debitCardExpress\"," + 63 "\"terminal_id\":\"NJ_T_001\"," + 64 "\"extend_params\":{" + 65 "\"sys_service_provider_id\":\"2088511833207846\"," + 66 "\"industry_reflux_info\":\"{\\\\\\\"scene_code\\\\\\\":\\\\\\\"metro_tradeorder\\\\\\\",\\\\\\\"channel\\\\\\\":\\\\\\\"xxxx\\\\\\\",\\\\\\\"scene_data\\\\\\\":{\\\\\\\"asset_name\\\\\\\":\\\\\\\"ALIPAY\\\\\\\"}}\"," + 67 "\"card_type\":\"S0JP0000\"" + 68 " }," + 69 "\"timeout_express\":\"90m\"," + 70 "\"settle_info\":{" + 71 " \"settle_detail_infos\":[{" + 72 " \"trans_in_type\":\"cardSerialNo\"," + 73 "\"trans_in\":\"A0001\"," + 74 "\"summary_dimension\":\"A0001\"," + 75 "\"settle_entity_id\":\"2088xxxxx;ST_0001\"," + 76 "\"settle_entity_type\":\"SecondMerchant、Store\"," + 77 "\"amount\":0.1" + 78 " }]" + 79 " }," + 80 "\"merchant_order_no\":\"20161008001\"," + 81 "\"business_params\":\"{\\\"data\\\":\\\"123\\\"}\"," + 82 "\"qr_code_timeout_express\":\"90m\"" + 83 " }"); 84 AlipayTradePrecreateResponse response; 85 try { 86 response = alipayClient.execute(request); 87 if(response.isSuccess()){ 88 System.out.println("調用成功"); 89 String qr_code = response.getQrCode(); 90 // 須要修改成運行機器上的路徑 91 String filePath = String.format("d:/qr-%s.png", 92 response.getOutTradeNo()); 93 System.out.println("filePath:" + filePath); 94 ZxingUtils.getQRCodeImge(response.getQrCode(), 256, filePath); 95 return qr_code; 96 } else { 97 System.out.println("調用失敗"); 98 return"調用失敗"; 99 } 100 } catch (AlipayApiException e) { 101 // TODO Auto-generated catch block 102 e.printStackTrace(); 103 return"調用異常"; 104 } 105 106 } 107 // 撤銷 108 public String cancel() { 109 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); 110 AlipayTradeCancelRequest request = new AlipayTradeCancelRequest(); 111 request.setBizContent("{" + 112 "\"out_trade_no\":\"20150320010101001\"," + 113 "\"trade_no\":\"2014112611001004680073956707\"" + 114 " }"); 115 AlipayTradeCancelResponse response; 116 try { 117 response = alipayClient.execute(request); 118 if(response.isSuccess()){ 119 System.out.println("調用成功"); 120 return "success"; 121 } else { 122 System.out.println("調用失敗"); 123 return "false"; 124 } 125 } catch (AlipayApiException e) { 126 // TODO Auto-generated catch block 127 e.printStackTrace(); 128 return "exception"; 129 } 130 131 } 132 public void query() { 133 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); 134 AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); 135 request.setBizContent("{" + 136 "\"out_trade_no\":\"20150320010101001\"," + 137 "\"trade_no\":\"2014112611001004680 073956707\"," + 138 "\"org_pid\":\"2088101117952222\"" + 139 " }"); 140 AlipayTradeQueryResponse response; 141 try { 142 response = alipayClient.execute(request); 143 if(response.isSuccess()){ 144 System.out.println("調用成功"); 145 } else { 146 System.out.println("調用失敗"); 147 } 148 } catch (AlipayApiException e) { 149 // TODO Auto-generated catch block 150 e.printStackTrace(); 151 } 152 153 } 154 // 退款 155 public void refund() { 156 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); 157 AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); 158 request.setBizContent("{" + 159 "\"out_trade_no\":\"20150320010101001\"," + 160 "\"trade_no\":\"2014112611001004680073956707\"," + 161 "\"refund_amount\":200.12," + 162 "\"refund_currency\":\"USD\"," + 163 "\"refund_reason\":\"正常退款\"," + 164 "\"out_request_no\":\"HZ01RF001\"," + 165 "\"operator_id\":\"OP001\"," + 166 "\"store_id\":\"NJ_S_001\"," + 167 "\"terminal_id\":\"NJ_T_001\"," + 168 " \"goods_detail\":[{" + 169 " \"goods_id\":\"apple-01\"," + 170 "\"alipay_goods_id\":\"20010001\"," + 171 "\"goods_name\":\"ipad\"," + 172 "\"quantity\":1," + 173 "\"price\":2000," + 174 "\"goods_category\":\"34543238\"," + 175 "\"categories_tree\":\"124868003|126232002|126252004\"," + 176 "\"body\":\"特價手機\"," + 177 "\"show_url\":\"http://www.alipay.com/xxx.jpg\"" + 178 " }]," + 179 " \"refund_royalty_parameters\":[{" + 180 " \"royalty_type\":\"transfer\"," + 181 "\"trans_out\":\"2088101126765726\"," + 182 "\"trans_out_type\":\"userId\"," + 183 "\"trans_in_type\":\"userId\"," + 184 "\"trans_in\":\"2088101126708402\"," + 185 "\"amount\":0.1," + 186 "\"amount_percentage\":100," + 187 "\"desc\":\"分帳給2088101126708402\"" + 188 " }]," + 189 "\"org_pid\":\"2088101117952222\"" + 190 " }"); 191 AlipayTradeRefundResponse response; 192 try { 193 response = alipayClient.execute(request); 194 if(response.isSuccess()){ 195 System.out.println("調用成功"); 196 } else { 197 System.out.println("調用失敗"); 198 } 199 } catch (AlipayApiException e) { 200 // TODO Auto-generated catch block 201 e.printStackTrace(); 202 } 203 204 } 205 206 public void refund_query() { 207 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); 208 AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); 209 request.setBizContent("{" + 210 "\"trade_no\":\"20150320010101001\"," + 211 "\"out_trade_no\":\"2014112611001004680073956707\"," + 212 "\"out_request_no\":\"2014112611001004680073956707\"," + 213 "\"org_pid\":\"2088101117952222\"" + 214 " }"); 215 AlipayTradeFastpayRefundQueryResponse response; 216 try { 217 response = alipayClient.execute(request); 218 if(response.isSuccess()){ 219 System.out.println("調用成功"); 220 } else { 221 System.out.println("調用失敗"); 222 } 223 } catch (AlipayApiException e) { 224 // TODO Auto-generated catch block 225 e.printStackTrace(); 226 } 227 228 } 229 230 231 //異步通知 232 @PostMapping("notify_url") 233 public void notify_url(HttpServletRequest request) { 234 //寫回調後的業務邏輯,按照相關api進行取值便可。 235 } 236 }
生成二維碼的工具類
1 package com.sharp.alipay.util; 2 3 import com.google.zxing.BarcodeFormat; 4 import com.google.zxing.EncodeHintType; 5 import com.google.zxing.MultiFormatWriter; 6 import com.google.zxing.common.BitMatrix; 7 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; 8 import org.apache.commons.logging.Log; 9 import org.apache.commons.logging.LogFactory; 10 11 import javax.imageio.ImageIO; 12 import java.awt.image.BufferedImage; 13 import java.io.File; 14 import java.io.IOException; 15 import java.util.Hashtable; 16 import java.util.Map; 17 18 /** 19 * Created by liuyangkly on 15/6/27. 20 * 使用了google zxing做爲二維碼生成工具 21 */ 22 public class ZxingUtils { 23 private static Log log = LogFactory.getLog(ZxingUtils.class); 24 25 private static final int BLACK = 0xFF000000; 26 private static final int WHITE = 0xFFFFFFFF; 27 28 private static BufferedImage toBufferedImage(BitMatrix matrix) { 29 int width = matrix.getWidth(); 30 int height = matrix.getHeight(); 31 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 32 for (int x = 0; x < width; x++) { 33 for (int y = 0; y < height; y++) { 34 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); 35 } 36 } 37 return image; 38 } 39 40 private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException { 41 BufferedImage image = toBufferedImage(matrix); 42 if (!ImageIO.write(image, format, file)) { 43 throw new IOException("Could not write an image of format " + format + " to " + file); 44 } 45 } 46 47 /** 將內容contents生成長寬均爲width的圖片,圖片路徑由imgPath指定 48 */ 49 public static File getQRCodeImge(String contents, int width, String imgPath) { 50 return getQRCodeImge(contents, width, width, imgPath); 51 } 52 53 /** 將內容contents生成長爲width,寬爲width的圖片,圖片路徑由imgPath指定 54 */ 55 public static File getQRCodeImge(String contents, int width, int height, String imgPath) { 56 try { 57 Map<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>(); 58 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); 59 hints.put(EncodeHintType.CHARACTER_SET, "UTF8"); 60 61 BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); 62 63 File imageFile = new File(imgPath); 64 writeToFile(bitMatrix, "png", imageFile); 65 66 return imageFile; 67 68 } catch (Exception e) { 69 log.error("create QR code error!", e); 70 return null; 71 } 72 } 73 }
啓動類沒有任何變更仍是生成項目的類
1 package com.sharp.alipay; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 6 @SpringBootApplication 7 public class AlipayApplication { 8 9 public static void main(String[] args) { 10 SpringApplication.run(AlipayApplication.class, args); 11 } 12 13 }
以上,就是整個支付寶整合的例子,本博主在工做上直接運行成功的,本篇博文,沒有再去進行實際測試,僅僅記錄一個對接支付寶的思路過程,總結記錄以備後用。