1.登陆支付宝开放平台
进入开发者中心
点击 研发服务
扫码 下载沙箱版支付宝
2.设置公钥私钥
然后下载密钥生成工具
生成完以后把(应用公钥)粘贴到沙箱环境中
下载沙箱版支付宝,账号密码在这
沙箱环境配置完毕
3.配置服务器
要添加一个支付宝的SDK的依赖
<!--支付宝的SDK-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.3.0.ALL</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
</exclusions>
</dependency>
4.创建一个pay.properties配置文件
注意要在spring配置文件中加载
改三个,用户私钥,阿里公钥,AAPID
#支付宝网关地址
serverUrl=https://openapi.alipaydev.com/gateway.do
#应用编号 自己的AAPID
appId=2016091300500103
#用户私钥 在公钥私钥生成工具里面粘贴
privateKey=用户私钥
#阿里公钥 在开放平台沙箱环境里面查看 然后 粘贴
alipayPulicKey=阿里公钥
#传递数据格式json
format=json
#编码
charset=utf-8
#加密方式
signType=RSA2
5.在spring配置文件中配置支付宝客户端对象的bean(记得扫描properties配置文件)
<!--配置支付宝客户端对象-->
<bean id="payClient" class="com.alipay.api.DefaultAlipayClient">
<constructor-arg name="serverUrl" value="${serverUrl}"/>
<constructor-arg name="appId" value="${appId}"/>
<constructor-arg name="privateKey" value="${privateKey}"/>
<constructor-arg name="format" value="${format}"/>
<constructor-arg name="charset" value="${charset}"/>
<constructor-arg name="alipayPublicKey" value="${alipayPulicKey}"/>
<constructor-arg name="signType" value="${signType}"/>
</bean>
6.编写一个预下单的代码
具体思路可查看这个
1.写一个接口pay_interface
参数1:订单编号 参数2:支付金额
package com.offcn.pay.service;
import java.util.Map;
/**
* 支付宝支付接口
* @author Administrator
*
*/
public interface AliPayService {
/**
* 生成支付宝支付二维码
* @param out_trade_no 订单号
* @param total_fee 金额(分)
* @return
*/
public Map createNative(String out_trade_no,String total_fee);
}
2.写实现类pay_service
传入参数
参数1:订单编号 参数2:支付金额
package com.offcn.pay.service.impl;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.offcn.pay.service.AliPayService;
import org.springframework.beans.factory.annotation.Autowired;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
public class AliPayServiceImpl implements AliPayService {
@Autowired
AlipayClient alipayClient;
@Override
public Map createNative(String out_trade_no, String total_fee) {
Map<String,String> map=new HashMap<String, String>();
//创建预下单请求对象
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
//转换下单金额按照元,因为传进来的金额单位是 分
long total = Long.parseLong(total_fee);
BigDecimal bigTotal = BigDecimal.valueOf(total);
BigDecimal cs = BigDecimal.valueOf(100d);
BigDecimal bigYuan = bigTotal.divide(cs);
System.out.println("预下单金额:"+bigYuan.doubleValue());
request.setBizContent("{" +
" \"out_trade_no\":\""+out_trade_no+"\"," + //商家订单号
" \"total_amount\":\""+bigYuan.doubleValue()+"\"," + //与下单金额 单位 :元
" \"subject\":\"优乐选商城商品\"," + //商家标题
" \"store_id\":\"xa_001\"," + //店铺编号
" \"timeout_express\":\"90m\"}");//设置业务参数 预下单失效时间 90m
//3.发出预下单业务请求
try {
AlipayTradePrecreateResponse response = alipayClient.execute(request);
//4.从相应对象读取相应结果
String code = response.getCode();
System.out.println("响应码:"+code);
//全部的响应结果
String body = response.getBody();
System.out.println("返回结果:"+body);
if(code!=null&&code.equals("10000")){
//获取响应订单二维码 并且 封装进去
map.put("qrcode", response.getQrCode());
//订单编号
map.put("out_trade_no", response.getOutTradeNo());
//订单金额
map.put("total_fee",total_fee);
System.out.println("qrcode:"+response.getQrCode());
System.out.println("out_trade_no:"+response.getOutTradeNo());
System.out.println("total_fee:"+total_fee);
}else{
System.out.println("预下单接口调用失败:"+body);
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return map;
}
}
7.测试访问接口
使用IdWorker工具类生成订单编号,这里测试金额写死 写成1
@RequestMapping("/createNative")
public Map createNative(){
//生成订单编号
long out_trade_no = idWorker.nextId();
Map map=payService.createNative(out_trade_no ,1+"");
}
return map;
}
访问接口进行测试
这个url地址就是生成二维码的地址,扫描二维码就可以支付了
关于二维码生成的方法,看我的另一篇博文
链接: 查看地址.
如何判断支付是否成功
思路:在生成二维码后,就立马访问判断支付是否成功的接口,并用一个死循环,不停的查询状态,可以设置可最大循环次数,超过次数就说明支付超时,是通过订单编号来查询的
8.实现类方法
public Map queryPayStatus(String out_trade_no){
System.out.println("需要查询支付状态的订单编号:"+out_trade_no);
Map map=new HashMap();
//1、创建交易查询请求对象
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
//2、设置查询参数
request.setBizContent("{" +
" \"out_trade_no\":\""+out_trade_no+"\"," +//设置电商平台生成订单编号
" \"trade_no\":\"\"}");//支付宝生成交易流水号
//发出查询
try {
AlipayTradeQueryResponse response = payClient.execute(request);
//获取响应状态码
String code = response.getCode();
System.out.println("交易查询返回结果:"+response.getBody());
if(code!=null&&code.equals("10000")){
//判断交易状态 交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
String tradeStatus = response.getTradeStatus();
//封装交易状态
map.put("tradestatus",response.getTradeStatus());
//支付宝生成交易流水号
map.put("trade_no",response.getTradeNo());
//订单编号
map.put("out_trade_no",out_trade_no);
}else {
System.out.println("交易查询失败:"+code);
}
} catch (AlipayApiException e) {
e.printStackTrace();
}
return map;
}
map里就封装了支付的状态,一共就四个值 //交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、
TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
TRADE_SUCCESS(交易支付成功)、
TRADE_FINISHED(交易结束,不可退款)
接口
这里采用while(true)循环,不断地去查询支付状态,可以设置个最大循环次数,支付结果用Map封装
//查询交易状态
@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no){
Result result=null;
int x=0;
while (true) {
//调用实现类方法
Map map = payService.queryPayStatus(out_trade_no);
if (map == null) {
//查询异常,不在查询
result = new Result(false, "请求交易状态查询服务异常");
//跳出循环
break;
}
//判断返回状态
//交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、
// TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、
// TRADE_SUCCESS(交易支付成功)、
// TRADE_FINISHED(交易结束,不可退款)
//判断交易状态为 TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)
if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_CLOSED")) {
result = new Result(false, "未付款交易超时关闭,或支付完成后全额退款");
break;
}
if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_SUCCESS")) {
result = new Result(true, "交易支付成功");
//调用订单服务 修改订单状态
orderService.uodateOrderStatus(out_trade_no,map.get("trade_no")+"");
break;
}
if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_FINISHED")) {
result = new Result(false, "交易结束,不可退款");
break;
}
if (map.get("tradestatus") != null && map.get("tradestatus").equals("TRADE_CLOSED")) {
result = new Result(false, "未付款交易超时关闭,或支付完成后全额退款");
break;
}
x++;
if(x>=99){
result=new Result(false,"二维码超时");
break;
}
//为了防止一直查询,网关屏蔽掉,可以让查询线程等待3秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}