新增stripe支付

This commit is contained in:
wuchunlei
2025-01-16 09:10:11 +08:00
parent a9b2425c1b
commit 9808d236e4
10 changed files with 462 additions and 13 deletions

View File

@@ -38,7 +38,7 @@
<qcloud.cos.version>4.4</qcloud.cos.version> <qcloud.cos.version>4.4</qcloud.cos.version>
<swagger.version>2.7.0</swagger.version> <swagger.version>2.7.0</swagger.version>
<joda.time.version>2.9.9</joda.time.version> <joda.time.version>2.9.9</joda.time.version>
<gson.version>2.8.5</gson.version> <gson.version>2.10.1</gson.version>
<fastjson.version>1.2.79</fastjson.version> <fastjson.version>1.2.79</fastjson.version>
<hutool.version>5.7.22</hutool.version> <hutool.version>5.7.22</hutool.version>
<lombok.version>1.18.4</lombok.version> <lombok.version>1.18.4</lombok.version>
@@ -56,6 +56,12 @@
</properties> </properties>
<dependencies> <dependencies>
<!--stripe支付-->
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>28.2.0</version>
</dependency>
<!--汉字转拼音--> <!--汉字转拼音-->
<dependency> <dependency>
<groupId>com.github.promeg</groupId> <groupId>com.github.promeg</groupId>

View File

@@ -69,6 +69,8 @@ public class ShiroConfig {
filterMap.put("/pay/payNotify","anon"); // 微信回调接口 filterMap.put("/pay/payNotify","anon"); // 微信回调接口
filterMap.put("/pay/refundNotify","anon"); // 微信退款回调接口 filterMap.put("/pay/refundNotify","anon"); // 微信退款回调接口
filterMap.put("/pay/paypal/receivePaypalStatus","anon"); // paypal回调接口 filterMap.put("/pay/paypal/receivePaypalStatus","anon"); // paypal回调接口
filterMap.put("/pay/stripe/callback","anon"); // stripe回调接口
filterMap.put("/pay/stripe/transfer","anon"); // stripe中转接口
filterMap.put("/weChat/**","anon"); filterMap.put("/weChat/**","anon");
filterMap.put("/book/baseArea/getAllBaseArea","anon");//登录前获取全部区域 filterMap.put("/book/baseArea/getAllBaseArea","anon");//登录前获取全部区域
// filterMap.put("/book/bookchaptercontent/**","anon"); // filterMap.put("/book/bookchaptercontent/**","anon");

View File

@@ -2,10 +2,10 @@ package com.peanut.modules.bookAbroad.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.github.promeg.pinyinhelper.Pinyin;
import com.peanut.common.utils.R; import com.peanut.common.utils.R;
import com.peanut.common.utils.ShiroUtils; import com.peanut.common.utils.ShiroUtils;
import com.peanut.config.Constants; import com.peanut.config.Constants;
import com.peanut.config.DelayQueueConfig;
import com.peanut.modules.book.service.BuyOrderService; import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.book.service.TransactionDetailsService; import com.peanut.modules.book.service.TransactionDetailsService;
import com.peanut.modules.book.service.UserEbookBuyService; import com.peanut.modules.book.service.UserEbookBuyService;
@@ -16,6 +16,8 @@ import com.peanut.modules.common.entity.UserEbookBuyEntity;
import com.peanut.modules.common.service.BookService; import com.peanut.modules.common.service.BookService;
import com.peanut.modules.common.service.MyUserService; import com.peanut.modules.common.service.MyUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@@ -41,6 +43,8 @@ public class OrderController {
private TransactionDetailsService transactionDetailsService; private TransactionDetailsService transactionDetailsService;
@Autowired @Autowired
private UserEbookBuyService userEbookBuyService; private UserEbookBuyService userEbookBuyService;
@Autowired
private RabbitTemplate rabbitTemplate;
//海外读书下单 //海外读书下单
@RequestMapping("/placeOrder") @RequestMapping("/placeOrder")
@@ -71,13 +75,6 @@ public class OrderController {
} }
buyOrder.setRealMoney(totalPrice); buyOrder.setRealMoney(totalPrice);
String bookName = bookEntity.getName(); String bookName = bookEntity.getName();
char[] cs = bookEntity.getName().toCharArray();
for (int i = 0; i < cs.length; i++) {
if (Pinyin.isChinese(cs[i])){
bookName = Pinyin.toPinyin(bookEntity.getName(), " ").toLowerCase();
break;
}
}
buyOrder.setRemark("Purchase the e-book '"+bookName+"'"); buyOrder.setRemark("Purchase the e-book '"+bookName+"'");
buyOrder.setOrderStatus("0"); buyOrder.setOrderStatus("0");
buyOrder.setOrderType("abroadBook"); buyOrder.setOrderType("abroadBook");
@@ -101,9 +98,22 @@ public class OrderController {
return R.error(500, "Insufficient Balance"); return R.error(500, "Insufficient Balance");
} }
} }
rabbitTemplate.convertAndSend(
DelayQueueConfig.ORDER_TO_BE_PAY_EXCHANGE,
DelayQueueConfig.ORDER_TO_BE_PAY_ROUTING_KEY,
buyOrder.getOrderId(),
messagePostProcessor()
);
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
result.put("orderSn", buyOrder.getOrderSn()); result.put("orderSn", buyOrder.getOrderSn());
return R.ok(result); return R.ok(result);
} }
private MessagePostProcessor messagePostProcessor() {
return message -> {
//设置有效期30分钟
message.getMessageProperties().setExpiration(String.valueOf(30 * 60 * 1000));
return message;
};
}
} }

View File

@@ -0,0 +1,9 @@
package com.peanut.modules.common.dao;
import com.github.yulichang.base.MPJBaseMapper;
import com.peanut.modules.common.entity.PayStripeOrder;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface PayStripeOrderDao extends MPJBaseMapper<PayStripeOrder> {
}

View File

@@ -0,0 +1,37 @@
package com.peanut.modules.common.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
//paypal支付实体
@Data
@TableName("pay_stripe_order")
public class PayStripeOrder implements Serializable {
private static final long serialVersionUID = 1L;
@TableId
private Integer id;
//用户Id
private Integer userId;
//订单Id
private Integer orderId;
//订单编号
private String orderSn;
//创建订单时间
private Date createTime;
//创建订单时的sessionId用于查询订单状态
private String sessionId;
//chargeId支付完成后的回调id用于退款
private String stripeId;
//金额
private String amount;
//付款时间
private Date payTime;
//回调数据
private String callbackData;
}

View File

@@ -0,0 +1,7 @@
package com.peanut.modules.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.modules.common.entity.PayStripeOrder;
public interface PayStripeOrderService extends IService<PayStripeOrder> {
}

View File

@@ -0,0 +1,13 @@
package com.peanut.modules.common.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.modules.common.dao.PayStripeOrderDao;
import com.peanut.modules.common.entity.PayStripeOrder;
import com.peanut.modules.common.service.PayStripeOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service("payStripeOrderService")
public class PayStripeOrderServiceImpl extends ServiceImpl<PayStripeOrderDao, PayStripeOrder> implements PayStripeOrderService {
}

View File

@@ -3,16 +3,20 @@ package com.peanut.modules.mq.Consumer;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.peanut.config.Constants; import com.peanut.config.Constants;
import com.peanut.config.DelayQueueConfig; import com.peanut.config.DelayQueueConfig;
import com.peanut.modules.book.service.*;
import com.peanut.modules.common.dao.BuyOrderProductDao; import com.peanut.modules.common.dao.BuyOrderProductDao;
import com.peanut.modules.common.dao.ShopProductDao; import com.peanut.modules.common.dao.ShopProductDao;
import com.peanut.modules.common.entity.BuyOrder; import com.peanut.modules.common.entity.*;
import com.peanut.modules.common.entity.BuyOrderProduct;
import com.peanut.modules.common.entity.ShopProduct;
import com.peanut.modules.book.service.BuyOrderService;
import com.peanut.modules.common.service.CouponService; import com.peanut.modules.common.service.CouponService;
import com.peanut.modules.common.service.PayStripeOrderService;
import com.peanut.modules.pay.stripe.StripeConfig;
import com.stripe.model.PaymentIntent;
import com.stripe.model.checkout.Session;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@@ -31,6 +35,20 @@ public class OrderCancelConsumer {
ShopProductDao shopProductDao; ShopProductDao shopProductDao;
@Autowired @Autowired
CouponService couponService; CouponService couponService;
@Autowired
private PayStripeOrderService payStripeOrderService;
@Autowired
private StripeConfig stripeConfig;
@Autowired
private UserEbookBuyService userEbookBuyService;
@Autowired
private BookBuyConfigService bookBuyConfigService;
@Autowired
private MyUserService userService;
@Autowired
private TransactionDetailsService transactionDetailsService;
@Autowired
private PayPaymentOrderService payPaymentOrderService;
@RabbitListener(queues = DelayQueueConfig.ORDER_CANCEL_DEAD_LETTER_QUEUE) @RabbitListener(queues = DelayQueueConfig.ORDER_CANCEL_DEAD_LETTER_QUEUE)
public void orderConsumer(String orderId) { public void orderConsumer(String orderId) {
@@ -39,6 +57,39 @@ public class OrderCancelConsumer {
return; return;
} }
if(Constants.ORDER_STATUS_TO_BE_PAID.equals(buyOrder.getOrderStatus())){ if(Constants.ORDER_STATUS_TO_BE_PAID.equals(buyOrder.getOrderStatus())){
if ("5".equals(buyOrder.getPaymentMethod())){
//查询订单,是否已完成但未收到回调
PayStripeOrder payStripeOrder = payStripeOrderService.getOne(new LambdaQueryWrapper<PayStripeOrder>()
.eq(PayStripeOrder::getOrderSn,buyOrder.getOrderSn()));
if (payStripeOrder != null) {
Session session = stripeConfig.queryOrderSession(payStripeOrder.getSessionId());
if (session != null&&"complete".equals(session.getStatus())){
payStripeOrder.setStripeId(session.getPaymentIntent());
PaymentIntent intent = stripeConfig.queryOrderIntent(session.getPaymentIntent());
payStripeOrder.setAmount(intent.getAmount()+"");
payStripeOrder.setPayTime(new Date(intent.getCreated()*1000));
payStripeOrder.setCallbackData(intent.toString());
payStripeOrderService.updateById(payStripeOrder);
if ("abroadBook".equals(buyOrder.getOrderType())){
userEbookBuyService.addBookForUser(buyOrder.getUserId(), Arrays.asList(buyOrder.getAbroadBookId()));
}
if ("point".equals(buyOrder.getOrderType())){
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigService.getById(buyOrder.getProductId());
MyUserEntity userEntity = userService.getById(buyOrder.getUserId());
String money = bookBuyConfigEntity.getMoney();
//更新账户余额
userService.rechargeHSPoint(userEntity,Integer.valueOf(money));
//插入虚拟币消费记录
transactionDetailsService.rechargeRecord(userEntity,money,payStripeOrder.getId(),"StripePay",buyOrder.getOrderSn());
//插入花生币充值记录
payPaymentOrderService.insertDetail(userEntity,bookBuyConfigEntity,payStripeOrder.getId().toString());
}
buyOrder.setOrderStatus("3");
buyOrderService.updateById(buyOrder);
return;
}
}
}
buyOrder.setOrderStatus(Constants.ORDER_STATUS_OUT_OF_TIME); buyOrder.setOrderStatus(Constants.ORDER_STATUS_OUT_OF_TIME);
//回滚优惠卷 //回滚优惠卷
if (buyOrder.getCouponId()!=null&&buyOrder.getCouponId()!=0){ if (buyOrder.getCouponId()!=null&&buyOrder.getCouponId()!=0){

View File

@@ -0,0 +1,133 @@
package com.peanut.modules.pay.stripe;
import com.peanut.modules.common.entity.BuyOrder;
import com.stripe.Stripe;
import com.stripe.model.Event;
import com.stripe.model.PaymentIntent;
import com.stripe.model.Price;
import com.stripe.model.checkout.Session;
import com.stripe.net.Webhook;
import com.stripe.param.PaymentIntentCreateParams;
import com.stripe.param.PriceCreateParams;
import com.stripe.param.checkout.SessionCreateParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.IOUtils;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
@Component
@Slf4j
public class StripeConfig {
private String apiKey = "sk_test_51QgdjVPKgQFCEmmSh73AmFpze4tU6bIbjXrcmN9RMwYOuMMKAwRvP6OAHdLZMwCbQDWka3iqrZMj0JpyFzpe6w5o00Val258i6";
private String endpointSecret = "whsec_nLR7C84EILXloWGc8wD9WZd4fTAscm5z";
//4242 4242 4242 4242
public Session createOrder(BuyOrder buyOrder,String successUrl,String cancelUrl){
try{
Stripe.apiKey = apiKey;
PriceCreateParams priceParams =
PriceCreateParams.builder()
.setCurrency("usd")
.setUnitAmount(buyOrder.getRealMoney().multiply(new BigDecimal(100)).longValue())//金额,单位为分所以*100
.setProductData(
PriceCreateParams.ProductData.builder().setName(buyOrder.getRemark()).build()
)
.build();
Price price = Price.create(priceParams);
// 生成付款link
SessionCreateParams sessionParams =
SessionCreateParams.builder()
.setMode(SessionCreateParams.Mode.PAYMENT)
.addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD)
.setSuccessUrl(successUrl)
.setCancelUrl(cancelUrl)
.setClientReferenceId(buyOrder.getOrderSn())
.setPaymentIntentData(SessionCreateParams.PaymentIntentData.builder()
.putMetadata("orderSn", buyOrder.getOrderSn()).build())// 构建付款成功后需要用到的参数
.addLineItem(
SessionCreateParams.LineItem.builder()
.setPrice(price.getId())
.setQuantity(1L).build()
)
.build();
Session session = Session.create(sessionParams);
log.info(">>>>>>>>>>>stripe下单返回的信息是 result = {}", session.toString());
return session;
}catch (Exception e) {
log.error(">>>>>>>>>>:stripe创建订单网络连接失败 reason = {}", e.getMessage());
e.printStackTrace();
return null;
}
}
public PaymentIntent createPaymentIntent(){
try{
Stripe.apiKey = apiKey;
PaymentIntentCreateParams params =
PaymentIntentCreateParams.builder()
.setAmount(2000L)
.setCurrency("usd")
.setAutomaticPaymentMethods(
PaymentIntentCreateParams.AutomaticPaymentMethods.builder()
.setEnabled(true)
.build()
)
.build();
PaymentIntent paymentIntent = PaymentIntent.create(params);
log.info(">>>>>>>>>>>stripeSession查询的信息是 result = {}", paymentIntent.toJson());
return paymentIntent;
}catch (Exception e) {
log.error(">>>>>>>>>>:stripeSession查询失败 reason = {}", e.getMessage());
e.printStackTrace();
return null;
}
}
public Session queryOrderSession(String stripeSessionId){
try{
Stripe.apiKey = apiKey;
Session session = Session.retrieve(stripeSessionId);
log.info(">>>>>>>>>>>stripeSession查询的信息是 result = {}", session.toJson());
return session;
}catch (Exception e) {
log.error(">>>>>>>>>>:stripeSession查询失败 reason = {}", e.getMessage());
e.printStackTrace();
return null;
}
}
public PaymentIntent queryOrderIntent(String stripeIntentId){
try{
Stripe.apiKey = apiKey;
PaymentIntent intent = PaymentIntent.retrieve(stripeIntentId);
log.info(">>>>>>>>>>>stripeIntent查询的信息是 result = {}", intent.toJson());
return intent;
}catch (Exception e) {
log.error(">>>>>>>>>>:stripeIntent查询失败 reason = {}", e.getMessage());
e.printStackTrace();
return null;
}
}
public Event callback(HttpServletRequest request){
try{
Stripe.apiKey = apiKey;
InputStream inputStream = request.getInputStream();
byte[] bytes = IOUtils.toByteArray(inputStream);
String payload = new String(bytes, StandardCharsets.UTF_8);
String sigHeader = request.getHeader("Stripe-Signature");
Event event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
log.info(">>>>>>>>>>>stripe回调的信息是 result = {}", event.toJson());
return event;
}catch (Exception e) {
log.error(">>>>>>>>>>:stripe回调失败 reason = {}", e.getMessage());
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,181 @@
package com.peanut.modules.pay.stripe;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.peanut.common.utils.R;
import com.peanut.modules.book.service.*;
import com.peanut.modules.common.entity.BookBuyConfigEntity;
import com.peanut.modules.common.entity.BuyOrder;
import com.peanut.modules.common.entity.MyUserEntity;
import com.peanut.modules.common.entity.PayStripeOrder;
import com.peanut.modules.common.service.PayStripeOrderService;
import com.stripe.Stripe;
import com.stripe.model.*;
import com.stripe.model.checkout.Session;
import com.stripe.param.PaymentIntentCreateParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
/**
* stripe支付
*/
@RestController
@RequestMapping("/pay/stripe")
@Slf4j
public class StripeController {
@Autowired
private StripeConfig stripeConfig;
@Autowired
private BuyOrderService buyOrderService;
@Autowired
private PayStripeOrderService payStripeOrderService;
@Autowired
private UserEbookBuyService userEbookBuyService;
@Autowired
private BookBuyConfigService bookBuyConfigService;
@Autowired
private MyUserService userService;
@Autowired
private TransactionDetailsService transactionDetailsService;
@Autowired
private PayPaymentOrderService payPaymentOrderService;
@RequestMapping("/createOrder")
public R createOrder(@RequestBody Map<String,Object> params){
int pso = payStripeOrderService.count(new LambdaQueryWrapper<PayStripeOrder>()
.eq(PayStripeOrder::getOrderSn,params.get("orderSn")));
if (pso > 0) {
return R.error("An order already exists, please place a new order.");
}
BuyOrder buyOrder = buyOrderService.getOne(new LambdaQueryWrapper<BuyOrder>()
.eq(BuyOrder::getOrderSn,params.get("orderSn")));
if (!"0".equals(buyOrder.getOrderStatus())){
return R.error("Abnormal order status");
}
if ("point".equals(buyOrder.getOrderType())){
buyOrder.setRemark("Recharge Virtual Coin");
}
Session session = stripeConfig.createOrder(
buyOrder,
params.get("successUrl").toString(),
params.get("cancelUrl").toString());
if (session != null) {
PayStripeOrder payStripeOrder = new PayStripeOrder();
payStripeOrder.setOrderId(buyOrder.getOrderId());
payStripeOrder.setOrderSn(buyOrder.getOrderSn());
payStripeOrder.setUserId(buyOrder.getUserId());
payStripeOrder.setCreateTime(new Date());
payStripeOrder.setSessionId(session.getId());
payStripeOrderService.save(payStripeOrder);
return R.ok().put("id",session.getId()).put("url",session.getUrl());
}else {
return R.error("failed");
}
}
@RequestMapping("/createPaymentIntent")
public R createPaymentIntent(){
PaymentIntent paymentIntent = stripeConfig.createPaymentIntent();
return R.ok().put("clientSecret",paymentIntent.getClientSecret());
}
@RequestMapping("/queryOrderSession")
public R queryOrderSession(@RequestBody Map<String,Object> params){
Session session = stripeConfig.queryOrderSession(params.get("stripeSessionId").toString());
return R.ok().put("url",session.toString());
}
@RequestMapping("/queryOrderIntent")
public R queryOrderIntent(@RequestBody Map<String,Object> params){
PaymentIntent intent = stripeConfig.queryOrderIntent(params.get("stripeIntentId").toString());
return R.ok().put("url",intent.toString());
}
@RequestMapping("/callback")
@Transactional
public void callback(HttpServletRequest request){
Event event = stripeConfig.callback(request);
if ("payment_intent.succeeded".equals(event.getType())){
StripeObject eventObj = event.getDataObjectDeserializer().getObject().get();
PaymentIntent intent = (PaymentIntent) eventObj;
Map<String, String> metaData = intent.getMetadata();//自定义传入的参数
String orderSn = metaData.get("orderSn");//自定义订单号
PayStripeOrder payStripeOrder = payStripeOrderService.getOne(new LambdaQueryWrapper<PayStripeOrder>()
.eq(PayStripeOrder::getOrderSn,orderSn));
payStripeOrder.setStripeId(intent.getId());
payStripeOrder.setAmount(intent.getAmount()+"");
payStripeOrder.setPayTime(new Date(intent.getCreated()*1000));
payStripeOrder.setCallbackData(intent.toString());
payStripeOrderService.updateById(payStripeOrder);
BuyOrder buyOrder = buyOrderService.getById(payStripeOrder.getOrderId());
if ("abroadBook".equals(buyOrder.getOrderType())){
userEbookBuyService.addBookForUser(buyOrder.getUserId(), Arrays.asList(buyOrder.getAbroadBookId()));
}
if ("point".equals(buyOrder.getOrderType())){
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigService.getById(buyOrder.getProductId());
MyUserEntity userEntity = userService.getById(buyOrder.getUserId());
String money = bookBuyConfigEntity.getMoney();
//更新账户余额
userService.rechargeHSPoint(userEntity,Integer.valueOf(money));
//插入虚拟币消费记录
transactionDetailsService.rechargeRecord(userEntity,money,payStripeOrder.getId(),"Stripe",buyOrder.getOrderSn());
//插入花生币充值记录
payPaymentOrderService.insertDetail(userEntity,bookBuyConfigEntity,payStripeOrder.getId().toString());
}
buyOrder.setOrderStatus("3");
buyOrderService.updateById(buyOrder);
}
}
@RequestMapping("/transfer")
public String transfer(String paymentStatus){
String res = "<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
"<meta charset=\"UTF-8\">\n" +
"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
"<title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
" <p class=\"test\" style=\"margin-top:40%; text-align: center; font-size: 16px; color: #333;\"><span id=\"num\">3</span>s后自动跳转页面</p >\n" +
" <p id=\"test\" style=\"text-align: center; font-size: 16px; color: #6bba6b;\">关闭页面</p >\n" +
"</body>" +
"\n" +
"<script type=\"text/javascript\" src=\"https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.1.js\">\n" +
"</script>\n" +
"<script>\n" +
"var num = 3;\n" +
"var statusValue = null;\n" +
"window.onload = function (){\n" +
" document.getElementById(\"num\").innerHTML = num\n" +
" document.addEventListener('UniAppJSBridgeReady', function() {\n" +
" document.getElementById(\"num\").innerHTML = num\n" +
" var timer = setInterval(() => {\n" +
" num--\n" +
" document.getElementById(\"num\").innerHTML = num\n" +
" if (num == 1) {\n" +
" clearInterval(timer)\n" +
" location.href = 'io.reading.test://stripe?paymentStatus="+paymentStatus+"';\n" +
" }\n" +
" }, 1000);\n" +
"\n" +
" document.getElementById('test').addEventListener('click', function(evt) {\n" +
" location.href = 'io.reading.test://stripe?paymentStatus="+paymentStatus+"'\n" +
" });\n" +
" });\n" +
"}\n" +
"</script>\n" +
"</html>\n";
return res;
}
}