diff --git a/pom.xml b/pom.xml
index 8ec5336d..3f0e4094 100644
--- a/pom.xml
+++ b/pom.xml
@@ -248,7 +248,7 @@
com.stripe
stripe-java
- 25.0.0
+ 26.2.0
@@ -271,8 +271,11 @@
s3control
-
-
+
+ com.google.code.gson
+ gson
+ 2.10.1
+
diff --git a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java
index 0d1bed1a..fdd4c6fe 100644
--- a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java
+++ b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java
@@ -50,7 +50,7 @@ public class AuthenticationFilter extends OncePerRequestFilter {
"/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl",
"/api/python/flush","/api/account/healthy","/api/ali-pay/trade/notify","/api/paypal/ipn/back","/api/alipay-hk/trade/notify",
"/api/portfolio/page", "/api/portfolio/detail", "/api/portfolio/commentPage", "/api/portfolio/viewsIncrease",
- "/api/account/designWorksRegister","/api/account/questionnaire"
+ "/api/account/designWorksRegister","/api/account/questionnaire","/api/stripe/trade/notify"
);
@Override
diff --git a/src/main/java/com/ai/da/controller/StripeController.java b/src/main/java/com/ai/da/controller/StripeController.java
new file mode 100644
index 00000000..a7f8f76c
--- /dev/null
+++ b/src/main/java/com/ai/da/controller/StripeController.java
@@ -0,0 +1,41 @@
+package com.ai.da.controller;
+
+import com.ai.da.common.response.Response;
+import com.ai.da.service.StripeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Api(tags = "Stripe模块")
+@Slf4j
+@RestController
+@RequestMapping("/api/stripe")
+public class StripeController {
+
+ @Resource
+ private StripeService stripeService;
+
+ @ApiOperation("创建支付链接")
+ @PostMapping("/createOrder/{amount}")
+ public Response pay(@PathVariable Integer amount) {
+ return Response.success(stripeService.pay(amount));
+ }
+
+ @ApiOperation("支付通知")
+ @PostMapping("/trade/notify")
+ public Response callback(HttpServletRequest request) throws ServletException, IOException {
+ Boolean result = stripeService.notify(request);
+ if (result){
+ return Response.success(200,"success");
+ }else {
+ return Response.fail(400,"failure");
+ }
+ }
+}
diff --git a/src/main/java/com/ai/da/service/PayPalCheckoutService.java b/src/main/java/com/ai/da/service/PayPalCheckoutService.java
index 450c521d..d9da17e4 100644
--- a/src/main/java/com/ai/da/service/PayPalCheckoutService.java
+++ b/src/main/java/com/ai/da/service/PayPalCheckoutService.java
@@ -19,6 +19,8 @@ public interface PayPalCheckoutService {
Boolean doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException;
+ String getBody(HttpServletRequest request) throws IOException;
+
Order queryOrder(String orderNo) throws SerializeException;
Order captureOrder(String orderId) throws IOException;
diff --git a/src/main/java/com/ai/da/service/StripeService.java b/src/main/java/com/ai/da/service/StripeService.java
new file mode 100644
index 00000000..c4a09be1
--- /dev/null
+++ b/src/main/java/com/ai/da/service/StripeService.java
@@ -0,0 +1,11 @@
+package com.ai.da.service;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public interface StripeService {
+
+ String pay(Integer quantity);
+
+ Boolean notify(HttpServletRequest request);
+}
diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java
index c6376ee0..5d73d098 100644
--- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java
+++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java
@@ -508,7 +508,7 @@ public class AccountServiceImpl extends ServiceImpl impl
QueryWrapper qw = new QueryWrapper<>();
qw.eq("BINARY user_email", accountTrialDTO.getEmail());
List accountList = accountMapper.selectList(qw);
- if (CollectionUtil.isNotEmpty(accountList)) {
+ if (CollectionUtil.isNotEmpty(accountList) && !accountList.get(0).getSystemUser().equals(0)) {
if (accountList.get(0).getIsTrial() == 1) {
throw new BusinessException("The email has already been registered", ResultEnum.PROMPT.getCode());
} else {
@@ -538,6 +538,7 @@ public class AccountServiceImpl extends ServiceImpl impl
account = CopyUtil.copyObject(accountList.get(0), Account.class);
account.setIsTrial(1);
account.setIsBeginner(1);
+ account.setSystemUser(3);
account.setValidStartTime(System.currentTimeMillis());
if (link) {
account.setValidEndTime(Instant.now().plus(14, ChronoUnit.DAYS).toEpochMilli());
diff --git a/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java b/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java
index f4fd04b4..796bea28 100644
--- a/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java
+++ b/src/main/java/com/ai/da/service/impl/PayPalCheckoutServiceImpl.java
@@ -189,7 +189,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
}
// Simple helper method to fetch request data as a string from HttpServletRequest object.
- private static String getBody(HttpServletRequest request) throws IOException {
+ public String getBody(HttpServletRequest request) throws IOException {
String body;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
diff --git a/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java
new file mode 100644
index 00000000..a984048d
--- /dev/null
+++ b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java
@@ -0,0 +1,285 @@
+package com.ai.da.service.impl;
+
+import com.ai.da.service.PayPalCheckoutService;
+import com.ai.da.service.StripeService;
+import com.stripe.Stripe;
+import com.stripe.exception.SignatureVerificationException;
+import com.stripe.exception.StripeException;
+import com.stripe.model.*;
+import com.stripe.model.checkout.Session;
+import com.stripe.model.issuing.Card;
+import com.stripe.net.Webhook;
+import com.stripe.param.*;
+import com.stripe.param.checkout.SessionCreateParams;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class StripeServiceImpl implements StripeService {
+
+ private static final String privateKey = "sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2";
+// private static final String privateKey = "pk_test_51P4ZZL02n1TEydyNluht6VDxnBMoBw8S524otzlXV3CMCZI8HmkcUr3CKy8Z0eQ2WssSJ9sAaZnIQJI04fARHHJi00pcIB4sKU";
+
+
+
+ // 1、创建customer,获取customerId
+ // 2、创建客户支付方式 (从前端获取)
+ // 3、创建支付 paymentIntent
+ // 4、确认订单
+ // 5、捕获金额(执行扣款操作)
+ public static String createCustomer() throws StripeException {
+ Stripe.apiKey = privateKey;
+
+ // Customer允许重复使用
+ CustomerCreateParams params =
+ CustomerCreateParams.builder()
+ .setName("xp")
+ .setEmail("xupei3360@163.com")
+ .build();
+
+ Customer customer = Customer.create(params);
+
+ return customer.getId();
+ }
+
+ public static String createPaymentMethod(String customerId) throws StripeException {
+
+ Stripe.apiKey = privateKey;
+
+ PaymentMethodCreateParams params =
+ PaymentMethodCreateParams.builder()
+ .setType(PaymentMethodCreateParams.Type.CARD)
+ .setCard(
+ // 测试中,不建议使用卡号,会不安全的异常,必须使用token(https://docs.stripe.com/testing?testing-method=tokens#visa)
+ PaymentMethodCreateParams.Token.builder().setToken("tok_visa").build()
+// PaymentMethodCreateParams.CardDetails.builder()
+// .setNumber("4242424242424242")
+// .setExpMonth(8L)
+// .setExpYear(2026L)
+// .setCvc("314")
+// .build()
+ )
+ .build();
+
+ PaymentMethod paymentMethod = PaymentMethod.create(params);
+
+ /*try{
+ Map card = new HashMap<>();
+ card.put("exp_month",8L);
+ card.put("exp_year",2026L);
+ card.put("number","4242 4242 4242 42422");
+ card.put("cvc","314");
+ Map params = new HashMap<>();
+ params.put("type", "card");
+ params.put("card", card);
+ PaymentMethod paymentMethod = PaymentMethod.create(params);
+ Map params2 = new HashMap<>();
+ params2.put("customer", customerId);
+ paymentMethod.attach(params2);
+ return paymentMethod.getId();
+ }catch (Exception e){
+ e.printStackTrace();
+ }*/
+// return null;
+ return paymentMethod.getId();
+ }
+
+ public static String createPaymentIntent(String paymentMethodId, String customerId) throws StripeException {
+ Stripe.apiKey = privateKey;
+
+ Long amount = 600L;
+ PaymentIntentCreateParams params =
+ PaymentIntentCreateParams.builder()
+ .setAmount(amount)
+// .setPaymentMethod(paymentMethodId)
+ .setCustomer(customerId)
+ .setCurrency("hkd")
+ .setAutomaticPaymentMethods(
+ PaymentIntentCreateParams.AutomaticPaymentMethods.builder()
+ .setEnabled(true)
+ .build()
+ )
+ .build();
+
+ PaymentIntent paymentIntent = PaymentIntent.create(params);
+ return paymentIntent.getId();
+ }
+
+ public static String confirmPaymentIntent(String clientSecret) throws StripeException {
+ Stripe.apiKey = privateKey;
+
+ PaymentIntent resource = PaymentIntent.retrieve(clientSecret);
+
+ PaymentIntentConfirmParams params =
+ PaymentIntentConfirmParams.builder()
+ .setPaymentMethod("pm_card_visa")
+ .setReturnUrl("https://www.example.com")
+ .build();
+
+ PaymentIntent paymentIntent = resource.confirm(params);
+ return paymentIntent.getId();
+ }
+
+ public String capturePaymentIntent(String clientSecret) throws StripeException {
+
+ Stripe.apiKey = privateKey;
+
+ PaymentIntent resource = PaymentIntent.retrieve(clientSecret);
+
+ PaymentIntentCaptureParams params = PaymentIntentCaptureParams.builder().build();
+
+ PaymentIntent paymentIntent = resource.capture(params);
+ return null;
+ }
+
+ public static void main(String[] args) throws StripeException {
+// String customerId = createCustomer();
+// log.info(customerId);
+ String paymentMethodId = createPaymentMethod("cus_Pvc92hQPBgLE2t");
+ log.info(paymentMethodId);
+// String substring = paymentMethodId.substring(0, paymentMethodId.lastIndexOf("_"));
+// log.info(substring);
+// log.info(substring.substring(0, substring.lastIndexOf("_")));
+// String paymentIntentId = createPaymentIntent(null, "cus_Pvc92hQPBgLE2t");
+// log.info(paymentIntentId);
+
+// confirmPaymentIntent("pi_3P5lr002n1TEydyN0caeqdfq");
+
+ }
+
+ public String pay(Integer quantity) {
+ Stripe.apiKey = privateKey;
+ try {
+ //创建产品
+ Map params = new HashMap<>();
+ params.put("name", "AiDA 积分");
+// PriceCreateParams.ProductData productData = new PriceCreateParams.ProductData.Builder().setName("AiDA 积分").build();
+ Product product = Product.create(params);
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+ String format = simpleDateFormat.format(new Date());
+
+ //创建价格
+ Map priceParams = new HashMap<>();
+// BigDecimal actualAmount = createOrderEntity.getAmount().multiply(BigDecimal.valueOf(100)); //stripe的默认单位是分,即传入的amount实际上小数点会被左移两位
+ BigDecimal actualAmount = new BigDecimal("600"); //stripe的默认单位是分,即传入的amount实际上小数点会被左移两位
+ //给price绑定元数据并更新price用于检索
+ Map metadata = new HashMap<>();
+ metadata.put("orderId", format);
+ priceParams.put("metadata", metadata); //通过订单号关联用于检索price信息(可选)
+ priceParams.put("unit_amount", actualAmount.intValue());
+ priceParams.put("currency", "HKD");
+ priceParams.put("product", product.getId());
+// priceParams.put("product_data", product.getId());
+// PriceCreateParams priceParam = PriceCreateParams.builder().setCurrency("HKD").setProductData(productData).setUnitAmount(Long.valueOf("6")).build();
+ Price price = Price.create(priceParams);
+
+ //创建支付信息得到url
+ SessionCreateParams params3 = SessionCreateParams.builder()
+ .setMode(SessionCreateParams.Mode.PAYMENT)
+ .setSuccessUrl("https://www.example.com") //可自定义成功页面
+ .setCancelUrl("https://www.example.com")
+ .addLineItem(
+ SessionCreateParams.LineItem.builder()
+ .setQuantity(Long.valueOf(quantity))
+ /*.setPriceData(
+ new SessionCreateParams.LineItem.PriceData.Builder()
+ .setCurrency("HKD")
+ .setUnitAmount(Long.valueOf("600"))
+ .setProductData(
+ new SessionCreateParams.LineItem.PriceData.ProductData.Builder()
+ .setName("AiDaA 积分")
+ .build())
+ .build())*/
+ .setPrice(price.getId())
+ .build())
+ .putMetadata("orderId",format) //通过订单号关联用于检索支付信息(可选)
+ .build();
+ Session session = Session.create(params3);
+ System.out.println("sessionId:" +session.getId());
+ String sessionId = session.getId(); //退款方式1:拿到sessionId入库,退款的时候根据这个id找到PaymentIntent的id然后发起退款
+ return session.getUrl();
+ }catch (Exception e){
+ log.error("创建支付会话出现异常:",e);
+ }
+ return "";
+ }
+
+ @Resource
+ private PayPalCheckoutService payPalCheckoutService;
+
+ @Override
+ public Boolean notify(HttpServletRequest request){
+ log.info("stripe异步通知进行中");
+ String payload = null;
+ String sigHeader= null;
+// String endpointSecret = "whsec_xxxgx92OjXdBf1lc2c";//webhook秘钥签名
+ String endpointSecret = "whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w";//webhook秘钥签名
+ try {
+ sigHeader = request.getHeader("Stripe-Signature");
+ payload = payPalCheckoutService.getBody(request);
+ } catch (Exception e) {
+ log.info("stripe 支付回调参数解析异常:errorMsg {}", e.getMessage());
+ log.info("request sigHeader = {}", sigHeader);
+ log.info("request body = {}", payload);
+ e.printStackTrace();
+ return Boolean.FALSE;
+// response.setStatus(400);
+ }
+
+ Event event = null;
+ try {
+ assert sigHeader != null;
+ event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
+ } catch (SignatureVerificationException e) {
+ log.info("stripe 验签,获取事件异常, errorMsg=" + e.getMessage());
+ log.info("request sigHeader = {}", sigHeader);
+ log.info("request body = {}", payload);
+ e.printStackTrace();
+ return Boolean.FALSE;
+// response.setStatus(400);
+ }
+
+
+ //获取自定义参数
+ // Deserialize the nested object inside the event
+ assert event != null;
+ EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
+ StripeObject stripeObject = null;
+ if (dataObjectDeserializer.getObject().isPresent()) {
+ stripeObject = dataObjectDeserializer.getObject().get();
+
+ } else {
+ log.info("stripe 验签失败!");
+ log.info("request sigHeader = {}", sigHeader);
+ log.info("request body = {}", payload);
+ return Boolean.FALSE;
+// response.setStatus(400);
+ }
+
+ if (event.getType().equals("checkout.session.completed")){
+
+ }
+ log.info("stripe验签成功");
+ return Boolean.TRUE;
+// response.setStatus(200);
+
+
+ // 1、验签
+
+ // 2、处理订单
+ // 2.1 更新订单状态
+ // 2.2 添加积分
+ }
+
+
+}