支付优化--修改积分购买相应功能

This commit is contained in:
2024-11-19 16:00:30 +08:00
parent 8d27b5b51e
commit f6f759110f
11 changed files with 81 additions and 52 deletions

View File

@@ -17,9 +17,9 @@ public interface CreditsService extends IService<CreditsDetail> {
String getCredits(Long accountId);
void creditsRefund(Long accountId, Integer quantity);
void creditsRefund(Long accountId, Integer quantity, String orderNo);
void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType);
void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo);
PageBaseResponse<CreditsDetail> queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO);

View File

@@ -217,7 +217,8 @@ public class AliPayServiceImpl implements AliPayService {
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive",
orderByOrderNo.getOrderNo());
} finally {
//要主动释放锁
lock.unlock();
@@ -320,7 +321,8 @@ public class AliPayServiceImpl implements AliPayService {
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive",
orderByOrderNo.getOrderNo());
}
}
@@ -393,7 +395,7 @@ public class AliPayServiceImpl implements AliPayService {
// 更新积分状态
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
} else {
log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg());

View File

@@ -248,7 +248,8 @@ public class AlipayHKServiceImpl implements AlipayHKService {
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive",
orderByOrderNo.getOrderNo());
log.info("用户:{} 积分信息更新成功",orderByOrderNo.getAccountId());
} finally {
//要主动释放锁

View File

@@ -100,7 +100,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
return account.getCredits().toString();
}
public void creditsRefund(Long accountId, Integer quantity) {
public void creditsRefund(Long accountId, Integer quantity, String orderNo) {
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
BigDecimal subtracted = existingCredits.subtract(newCredits);
@@ -111,7 +111,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
insertToCreditsDetail(accountId,
CreditsEventsEnum.REFUND.getName() + "--Stripe",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"negative");
"negative", orderNo);
}
/**
@@ -122,7 +122,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
* @param changeType 变更类型 positive->增 negative->减
*/
@Override
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType) {
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo) {
CreditsDetail creditsDetail = new CreditsDetail();
Account account = accountMapper.selectById(accountId);
// BigDecimal finalCredits;
@@ -137,6 +137,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
creditsDetail.setAccountId(accountId);
creditsDetail.setChangeEvent(changeEvent);
creditsDetail.setChangedCredits(changeCredits);
creditsDetail.setTaskId(orderNo);
// creditsDetail.setCredits(finalCredits);
creditsDetail.setCredits(account.getCredits());
creditsDetail.setCreateTime(LocalDateTime.now());

View File

@@ -280,7 +280,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
if (b) creditsService.insertToCreditsDetail(accountId,
CreditsEventsEnum.TO_PRODUCT_IMAGE.getName(),
CreditsEventsEnum.TO_PRODUCT_IMAGE.getValue(),
"negative");
"negative", null);
}
}
@@ -736,7 +736,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
if (b) creditsService.insertToCreditsDetail(accountId,
CreditsEventsEnum.RELIGHT.getName(),
CreditsEventsEnum.RELIGHT.getValue(),
"negative");
"negative", null);
}
}

View File

@@ -441,11 +441,11 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
* 申请退款
*/
@Transactional(rollbackFor = Exception.class)
public Boolean refundOrder(String orderId, String reason) throws IOException {
public Boolean refundOrder(String orderNo, String reason) throws IOException {
RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderId, reason);
RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderNo, reason);
OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderId);
OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderNo);
PayPalClient payPalClient = new PayPalClient();
HttpResponse<com.paypal.orders.Order> ordersGetResponse = null;
ordersGetRequest.authorization("Bearer " + getOAuth());
@@ -461,7 +461,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
request.authorization("Bearer " + getOAuth());
request.prefer("return=representation");
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason));
HttpResponse<com.paypal.payments.Refund> response = null;
try {
@@ -476,7 +476,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_SUCCESS);
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_SUCCESS);
refundsInfoService.updateRefundForPayPal(
refundByOrderNo.getId(),
@@ -485,14 +485,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
AliPayTradeStateEnum.REFUND_SUCCESS.getType()); //退款成功
// 更新积分状态
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderId);
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
log.info("退款成功");
result = Boolean.TRUE;
} else {
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL);
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_ABNORMAL);
//更新退款单
refundsInfoService.updateRefundForPayPal(
@@ -571,19 +571,19 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
// 处理当前订单
@Transactional(rollbackFor = Exception.class)
public void processOrder(String orderId) {
public void processOrder(String orderNo) {
// 1、确定当前订单是否已经被扣款
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) {
// 直接返回
return;
}
// 发起扣款请求
Order capturedOrder = captureOrder(orderId);
Order capturedOrder = captureOrder(orderNo);
// 业务处理
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) {
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS);
//记录支付日志
paymentInfoService.createPaymentInfoForPayPal(capturedOrder);
float quantity = orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue());
@@ -593,7 +593,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
creditsService.insertToCreditsDetail(orderInfo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--PayPal",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive", orderNo);
}
}
@@ -637,7 +637,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--Paypal",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive", orderNo);
}
}

View File

@@ -187,10 +187,15 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
// 判断当前支付是否已经被记录,确保同一个支付不会被重复记录
if (Objects.isNull(paymentInfo)){
String orderNo;
String subscriptionId = invoice.getSubscription();
try {
// 从subscription中获取orderNo
orderNo = Subscription.retrieve(subscriptionId).getDescription().replace("AiDA - ", "");
if (invoice.getBillingReason().equals("manual")){
// 手动创建的发票针对one-time支付
orderNo = invoice.getLines().getData().get(0).getPrice().getMetadata().get("orderId");
}else {
String subscriptionId = invoice.getSubscription();
// 从subscription中获取orderNo
orderNo = Subscription.retrieve(subscriptionId).getDescription().replace("AiDA - ", "");
}
} catch (StripeException e) {
throw new RuntimeException(e);
}

View File

@@ -41,6 +41,7 @@ import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
@SuppressWarnings("LoggingSimilarMessage")
@@ -79,8 +80,9 @@ public class StripeServiceImpl implements StripeService {
ProductEnum productEnum;
switch (productPurchaseDTO.getProductName()){
case "Credits Purchase":
case "CreditsPurchase":
productEnum = ProductEnum.CreditsProduct;
productPurchaseDTO.setAutoRenewal(false);
break;
case "Subscription":
switch (productPurchaseDTO.getSubscribeType()){
@@ -130,6 +132,8 @@ public class StripeServiceImpl implements StripeService {
}else {
sessionBuilder.setMode(SessionCreateParams.Mode.PAYMENT);
sessionBuilder.setPaymentIntentData(SessionCreateParams.PaymentIntentData.builder().setDescription("AiDA - " + orderId).build());
// one-time 手动创建发票;订阅会自动创建invoice
sessionBuilder.setInvoiceCreation(SessionCreateParams.InvoiceCreation.builder().setEnabled(Boolean.TRUE).build());
}
sessionBuilder.setCustomer(customerId);
sessionBuilder.setSuccessUrl(productPurchaseDTO.getReturnUrl());//可自定义成功页面
@@ -338,7 +342,7 @@ public class StripeServiceImpl implements StripeService {
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
CreditsEventsEnum.BUY_CREDITS.getName() + "--Stripe",
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
"positive");
"positive", orderId);
log.info("用户:{} 积分信息更新成功", orderByOrderNo.getAccountId());
}
} catch (Exception e) {
@@ -396,6 +400,10 @@ public class StripeServiceImpl implements StripeService {
return outputFormat.format(date);
}
public String changeTimeStampFormat(LocalDateTime localDate){
return localDate.format(DateTimeFormatter.ofPattern("MMM. dd, yyyy, EEEE", Locale.US));
}
@Transactional(rollbackFor = Exception.class)
public Boolean updateSubscription(Subscription subscription){
// 获取当前是否有已经记录的subscriptionInfo
@@ -457,14 +465,14 @@ public class StripeServiceImpl implements StripeService {
});
}
public String refund(String amount, String orderId, String reason) {
public String refund(String amount, String orderNo, String reason) {
Refund refund;
RefundInfo refundByOrderNo = refundInfoService.createRefundByOrderNo(orderId, reason);
RefundInfo refundByOrderNo = refundInfoService.createRefundByOrderNo(orderNo, reason);
try {
Stripe.apiKey = privateKey;
// 根据orderId找到对应的sessionId
String sessionId = paymentInfoService.getPaymentInfoByOrderId(orderId).getTransactionId();
String sessionId = paymentInfoService.getPaymentInfoByOrderId(orderNo).getTransactionId();
if (StringUtils.isNotEmpty(sessionId)) { //根据会话编号退款
Session session = Session.retrieve(sessionId);
@@ -498,7 +506,7 @@ public class StripeServiceImpl implements StripeService {
if ("succeeded".equals(refund.getStatus())) {
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_SUCCESS);
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_SUCCESS);
refundInfoService.updateRefundForPayPal(
refundByOrderNo.getId(),
@@ -507,11 +515,11 @@ public class StripeServiceImpl implements StripeService {
AliPayTradeStateEnum.REFUND_SUCCESS.getType()); //退款成功
// 更新积分状态
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderId);
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int) (orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int) (orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
} else {
//更新订单状态
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL);
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_ABNORMAL);
//更新退款单
refundInfoService.updateRefundForPayPal(
@@ -598,9 +606,17 @@ public class StripeServiceImpl implements StripeService {
try {
Stripe.apiKey = privateKey;
Invoice invoice = Invoice.retrieve(invoiceId);
PaymentIntent paymentIntent = PaymentIntent.retrieve(invoice.getPaymentIntent());
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentIntent.getPaymentMethod());
return getPaymentMethod(paymentMethod.getId());
if (!StringUtil.isNullOrEmpty(invoice.getPaymentIntent())){
PaymentIntent paymentIntent = PaymentIntent.retrieve(invoice.getPaymentIntent());
if (!StringUtil.isNullOrEmpty(paymentIntent.getPaymentMethod())){
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentIntent.getPaymentMethod());
return getPaymentMethod(paymentMethod.getId());
}
}
HashMap<String, String> resp = new HashMap<>();
resp.put("paymentMethod", null);
resp.put("last4", null);
return resp;
} catch (StripeException e) {
throw new RuntimeException(e);
}
@@ -668,15 +684,15 @@ public class StripeServiceImpl implements StripeService {
return false;
}
PaymentInfo paymentInfo = paymentInfos.get(0);
if (paymentInfo.getNotified() == 1){
// 已经邮件通知过,直接返回
return true;
}
if (StringUtil.isNullOrEmpty(type)){
// 如果没有传入type,则使用paymentInfo中记录的类型
// 其实这里也可以通过invoiceId查询stripe但是记录在自己的db中可以不用每次都查且方便查看
type = paymentInfo.getType();
}
if (!type.equals("reminder") && paymentInfo.getNotified() == 1){
// 已经邮件通知过,直接返回
return true;
}
com.ai.da.mapper.primary.entity.Account account = accountMapper.selectById(subscriptionInfo.getAccountId());
String userName = account.getUserName();
@@ -692,18 +708,20 @@ public class StripeServiceImpl implements StripeService {
emailParamsDTO.setPaymentMethod(subscriptionInfo.getPaymentMethod());
emailParamsDTO.setSubscriptionId(subscriptionInfo.getId().toString());
emailParamsDTO.setSubscriptionType(subscriptionInfo.getType());
emailParamsDTO.setStartDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodStart(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setStartDate(changeTimeStampFormat(subscriptionInfo.getCreateTime()));
emailParamsDTO.setNextPayDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setRenewalTime(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
// 邮件通知成功后,更新标志
PaymentInfo payment = new PaymentInfo();
payment.setId(paymentInfo.getId());
payment.setNotified(1);
payment.setUpdateTime(LocalDateTime.now());
paymentInfoMapper.updateById(payment);
if (!type.equals("reminder")){
PaymentInfo payment = new PaymentInfo();
payment.setId(paymentInfo.getId());
payment.setNotified(1);
payment.setUpdateTime(LocalDateTime.now());
paymentInfoMapper.updateById(payment);
}
return true;
}
@@ -723,7 +741,7 @@ public class StripeServiceImpl implements StripeService {
List<SubscriptionInfo> subscriptionInfos = subscriptionInfoMapper.selectList(qw);
for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
boolean b = sendEmail(subscriptionInfo.getSubscriptionId(), null);
boolean b = sendEmail(subscriptionInfo.getSubscriptionId(), "reminder");
if (b) log.info("提前7天向用户 {} 发送续订通知邮件", subscriptionInfo.getAccountId());
}
}

View File

@@ -149,7 +149,7 @@ public class SuperResolutionServiceImpl extends ServiceImpl<TaskListMapper, Task
creditsService.insertToCreditsDetail(accountId,
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
"negative");
"negative", null);
}
}