支付宝沙箱支付
1.gav坐标
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.0.2</version>
</dependency>
2.application.properties配置
alipay.appId= //用户宝ID号
alipay.privateKey= //私钥
alipay.publicKey= //公钥
alipay.gateway=openapi.alipaydev.com //网关
alipay.notifyUrl= //回调函数
alipay.returnUrl= //返回页面
3.项目初始化,单独创一个包,这里面的东西不需要修改。
@Component
public class ProjectInit implements ApplicationRunner {
//应用id
@Value("${alipay.appId}")
private String appId;
//私钥
@Value("${alipay.privateKey}")
private String privateKey;
//公钥
@Value("${alipay.publicKey}")
private String publicKey;
//支付宝网关
@Value("${alipay.gateway}")
private String gateway;
//支付成功后的接口回调地址,不是回调的友好页面,不要弄混了
@Value("${alipay.notifyUrl}")
private String notifyUrl;
/**
* 项目初始化事件
* */
@Override
public void run(ApplicationArguments args) throws Exception {
//初始化支付宝SDK
Factory.setOptions(getOptions());
System.out.println("**********支付宝SDK初始化完成**********");
}
private Config getOptions() {
Config config = new Config();
config.protocol = "https";
config.gatewayHost = this.gateway;
config.signType = "RSA2";
config.appId = this.appId;
config.merchantPrivateKey = this.privateKey;
config.alipayPublicKey = this.publicKey;
config.notifyUrl = notifyUrl;
return config;
}
}
4.业务层
@Service
public class PayService {
@Autowired
private UserInfoService userInfoService; //这个是自己数据库的接口。
//支付成功后要跳转的页面
@Value("${alipay.returnUrl}")
private String returnUrl;
/**
* 下单支付
* */
public Object pay (OrderBO orderBo) throws Exception {
// i 这个是自己的业务
int i = userInfoService.putUserIntegral(String.valueOf(orderBo.getIntegral()),String.valueOf(orderBo.getUserId()));
//调用sdk,发起支付
AlipayTradePagePayResponse response = Factory.Payment
//选择网页支付平台
.Page()
//调用支付方法,设置订单名称、我们自己系统中的订单号、金额、回调页面
.pay("支付订单", OrderUtil.getOrderNo(), String.valueOf(orderBo.getMoney()) , returnUrl);
//这里的response.body,就是一个可以直接加载的html片段。
return response.body;
}
}
5.控制层
@Autowired
private PayService payService;
/**
* 下单支付
*/
//这个头信息不要修改
@PostMapping(value = "/confirm", produces = {"application/json;charset=UTF-8"})
public Object pay(@RequestBody OrderBO orderBO) throws Exception {
System.out.println(orderBO);
// bo = new PaymentBO();
return new Message(200, "ok", payService.pay(orderBO));
// return payService.pay();
}
//重要,前端写一个点击事件、触发这个控制器,首先把返回的data值取出,然后利用jQuery解析,把HTML片段解析出来,之后就可以自动跳转,jquery解析利用$("").html("这里填写片段");如果是vue的话,思路也是一样、只是实现方式不一样,也是先获取然后解析,vue利用v-html.
6.订单编号生成,时间戳
public class OrderUtil {
/**
* 根据时间戳生成订单号
* */
public static String getOrderNo () {
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
LocalDateTime localDateTime = Instant.ofEpochMilli(System.currentTimeMillis()).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
return df.format(localDateTime);
}
7.实体BO类,这个根据自己的业务去创建。
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class OrderBO {
private Integer money;
private Integer integral;
private Integer userId;
}