最近公司要做一个有关支付的相关项目,需要对接支付宝的支付接口,实现扫描二维码支付功能,为此研究了一下支付宝相关业务。主要依据就是支付宝的相关接口文档:

https://docs.open.alipay.com/catalog,重点关注如下红色方框部分

 先看一下支付宝扫描二维码支付的业务流程,直接摘出来如下:

扫码支付(接入指引

扫码支付,指用户打开支付宝钱包中的“扫一扫”功能,扫描商家展示在某收银场景下的二维码并进行支付的模式。该模式适用于线下实体店支付、面对面支付等场景。

业务流程:

使用步骤:

  1. 收银员在商家收银系统操作生成支付宝订单,并生成二维码;
  2. 用户登录支付宝钱包,点击首页“付款-扫码付”或直接点击“扫一扫”,进入扫一扫界面;
  3. 用户扫收银员提供的二维码,核对金额,确认支付;
  4. 用户付款后商家收银系统会拿到支付成功或者失败的结果。

产品特点:

  • 用户仅出示手机扫码即可完成付款,方便快捷;
  • 资金实时到账,无现金流压力。

  基本上我们开发常用的也就是一个生成二维码的预创建订单接口,一个取消,一个退款,一个支付成功后的回调接口

接下来,我们开始准备环境进行开发,不管是运行官方的demo还是集成到项目中,我们都需要进行相应的环境准备,目前,网上的沙箱环境比较多,我就直接配置个人商家的真实环境来记录博客,沙箱环境本博主在公司里面搭建过,今天在家就用自己支付宝开发商家环境,更为真实的记录这个过程。

其实支付宝这块的api开发接口文档等还是写的比较明白的,如果真的是有搞不定的地方也是可以在线询问支付宝技术客服的,而且回复的速度也是挺快。现在支付宝的验签功能已经封装了,不需要我们在自己实现验签功能。挺方便

配置环境我们直接点击上面的连接接入指引按照步骤进行:

一、创建应用

 

 创建完成就分配了appid,

 

 

 红框设置步骤如下:

设置应用公钥

保存之后生成支付宝公钥

上述全部设置完成以后提交审核

 接下来等待审核通过即可,

DEMO运行

下载demo地址——->  https://docs.open.alipay.com/194/105201/

解压后然后导入普通工程

导入后目录结构如下

 

 然后根据demo进行

# 直接运行demo步骤如下(eclipse直接导入工程即可):
1、请先确认zfbinfo.properties配置文件是否已配置完成
2、运行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

View Code

 只要填写正确就可以直接通过main方法测试运行。

接下来我们看看怎么集成到我们自己的项目中,作为一个接口提供出去给前端或者app调用,这个其实demo里面readme也说的很清楚,先把readme整个贴出来

DEMO里的readme

  1 # DEMO仅供参考,实际开发中需要结合具体业务场景修改使用
  2 #
  3 # 运行环境:jdk1.6及以上
  4 # 当面付2.0demo使用前必读
  5 
  6 # 直接运行demo步骤如下(eclipse直接导入工程即可):
  7 1、请先确认zfbinfo.properties配置文件是否已配置完成
  8 2、运行Main.java中的main方法
  9 
 10 # 集成至商户系统步骤如下(以maven工程结构为例):
 11 1、拷贝java目录下的Main.java(和DemoHbRunner.java,如果需要集成交易保障接口)至系统商源代码目录
 12 2、将lib目录下所有jar文件添加至系统商lib目录,如果没有alipay-trade-sdk.jar(此jar包集成了当面付交易逻辑和交易保障接口),则将TradePaySDK编译为该jar包
 13 3、拷贝resources目录下的配置文件至系统商classpath根目录
 14 4、在系统商项目中运行Main方法,确认集成无误
 15 5、系统商使用main方法中的调用样例进行商户端系统开发
 16 
 17 Q:扫码支付、统一下单+JSAPI唤起收银台支付后,支付成功异步通知如何处理?
 18 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
 19 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
 20 3、校验通知中的seller_id(或者seller_email) 是否为该笔交易对应的操作方(一个商户可能有多个seller_id/seller_email)
 21 4、验证接口调用方的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仅供参考,实际开发中需要结合具体业务场景修改使用

View Code

重点是:

# 集成至商户系统步骤如下(以maven工程结构为例):
1、拷贝java目录下的Main.java(和DemoHbRunner.java,如果需要集成交易保障接口)至系统商源代码目录
2、将lib目录下所有jar文件添加至系统商lib目录,如果没有alipay-trade-sdk.jar(此jar包集成了当面付交易逻辑和交易保障接口),则将TradePaySDK编译为该jar包
3、拷贝resources目录下的配置文件至系统商classpath根目录
4、在系统商项目中运行Main方法,确认集成无误
5、系统商使用main方法中的调用样例进行商户端系统开发

Q:扫码支付、统一下单+JSAPI唤起收银台支付后,支付成功异步通知如何处理?
1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
3、校验通知中的seller_id(或者seller_email) 是否为该笔交易对应的操作方(一个商户可能有多个seller_id/seller_email)
4、验证接口调用方的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>

View Code

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

View Code

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 }

View Code

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 }

View Code

生成二维码的工具类

 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 }

View Code

启动类没有任何变动还是生成项目的类

 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 }

View Code

 

以上,就是整个支付宝整合的例子,本博主在工作上直接运行成功的,本篇博文,没有再去进行实际测试,仅仅记录一个对接支付宝的思路过程,总结记录以备后用。

 

版权声明:本文为xiaoyao-001原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/xiaoyao-001/p/10122856.html