支付优化
This commit is contained in:
@@ -17,6 +17,11 @@ public enum OrderStatusEnum {
|
||||
*/
|
||||
SUCCESS("支付成功"),
|
||||
|
||||
/**
|
||||
* 支付失败
|
||||
*/
|
||||
FAILURE("支付失败"),
|
||||
|
||||
/**
|
||||
* 已关闭
|
||||
*/
|
||||
|
||||
@@ -779,6 +779,8 @@ public class SendEmailUtil {
|
||||
private final static Long RENEWAL_USER_CN = 130726L;
|
||||
private final static Long RENEWAL_REMINDER_USER_EN = 130727L;
|
||||
private final static Long RENEWAL_REMINDER_USER_CN = 130728L;
|
||||
private final static Long PAYMENT_FAILED_NEW_MERCHANT_EN = 131230L;
|
||||
private final static Long PAYMENT_FAILED_RENEWAL_MERCHANT_EN = 131225L;
|
||||
|
||||
public static void subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress){
|
||||
try{
|
||||
@@ -807,6 +809,14 @@ public class SendEmailUtil {
|
||||
merchant.setSubject("[Code-Create] Subscription Cancelled");
|
||||
templateMerchant.setTemplateID(CANCEL_MERCHANT_EN);
|
||||
break;
|
||||
case "fail_new":
|
||||
merchant.setSubject("[Code-Create] Payment Failed : New Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||
templateMerchant.setTemplateID(PAYMENT_FAILED_NEW_MERCHANT_EN);
|
||||
break;
|
||||
case "fail_renewal":
|
||||
merchant.setSubject("[Code-Create] Payment Failed : Renewal Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||
templateMerchant.setTemplateID(PAYMENT_FAILED_RENEWAL_MERCHANT_EN);
|
||||
break;
|
||||
case "new":
|
||||
merchant.setSubject("[Code-Create] New Order(" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||
templateMerchant.setTemplateID(NEW_MERCHANT_EN);
|
||||
@@ -849,14 +859,14 @@ public class SendEmailUtil {
|
||||
templateMerchant.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
|
||||
merchant.setTemplate(templateMerchant);
|
||||
|
||||
if (!type.equals("cancel")){
|
||||
if (!type.equals("cancel") && !type.equals("fail_new") && !type.equals("fail_renewal") ){
|
||||
// 返回的resp是一个SendEmailResponse的实例,与请求对象对应
|
||||
SendEmailResponse respUser = client.SendEmail(user);
|
||||
log.info("邮件发送结果toUser###{}", SendEmailResponse.toJsonString(respUser));
|
||||
log.info("邮件主题:{},发送结果toUser###{}", user.getSubject(), SendEmailResponse.toJsonString(respUser));
|
||||
}
|
||||
if (!type.equals("reminder")){
|
||||
SendEmailResponse respMerchant = client.SendEmail(merchant);
|
||||
log.info("邮件发送结果toMerchant###{}", SendEmailResponse.toJsonString(respMerchant));
|
||||
log.info("邮件主题:{},发送结果toMerchant###{}", merchant.getSubject(), SendEmailResponse.toJsonString(respMerchant));
|
||||
}
|
||||
} catch (TencentCloudSDKException e) {
|
||||
log.info("邮件发送失败###{}", e.toString());
|
||||
|
||||
@@ -21,5 +21,7 @@ public class OrderInfo extends BaseEntity{
|
||||
|
||||
private String orderStatus;//订单状态
|
||||
|
||||
private String note;
|
||||
|
||||
private String paymentType;//支付方式
|
||||
}
|
||||
|
||||
@@ -26,4 +26,8 @@ public class PaymentInfo extends BaseEntity{
|
||||
|
||||
// 当前支付是否已邮件通知 0 || 1
|
||||
private Integer notified;
|
||||
|
||||
private String paymentMethod;
|
||||
|
||||
private String last4;
|
||||
}
|
||||
|
||||
@@ -22,14 +22,7 @@ public class SubscriptionInfo extends BaseEntity{
|
||||
// active || expired
|
||||
private String status = "active";
|
||||
|
||||
// 是否自动续订
|
||||
private byte autoRenewal = (byte)1;
|
||||
|
||||
// 支付方式
|
||||
private String paymentMethod;
|
||||
|
||||
// 如果是用卡支付,可以看到银行卡最后四位
|
||||
private String last4;
|
||||
private byte cancelNotified = (byte)0;
|
||||
|
||||
// 续订的下一个付款日
|
||||
private String nextPayDate;
|
||||
|
||||
@@ -28,6 +28,8 @@ public class SubscriptionEmailParamsDTO {
|
||||
// 付款方式
|
||||
private String paymentMethod;
|
||||
|
||||
private String last4;
|
||||
|
||||
// 订阅Id
|
||||
private String subscriptionId;
|
||||
|
||||
@@ -43,5 +45,8 @@ public class SubscriptionEmailParamsDTO {
|
||||
// 下次付款时间(reminder)
|
||||
private String renewalTime;
|
||||
|
||||
// 付款失败原因
|
||||
private String failMessage;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||
import com.ai.da.model.dto.AlipayHKCallbackDTO;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.paypal.orders.Order;
|
||||
import com.stripe.model.Charge;
|
||||
import com.stripe.model.Invoice;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -18,7 +19,9 @@ public interface PaymentInfoService extends IService<PaymentInfo> {
|
||||
|
||||
void createPaymentInfoForAliPayHK(AlipayHKCallbackDTO alipayHKCallbackDTO);
|
||||
|
||||
PaymentInfo createPaymentInfoForStripe(Invoice invoice);
|
||||
PaymentInfo createOrUpdatePaymentInfoForStripe(Invoice invoice);
|
||||
|
||||
PaymentInfo createOrUpdatePaymentInfoForStripe(Charge charge);
|
||||
|
||||
PaymentInfo getPaymentInfoByOrderId(String orderId);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.gson.Gson;
|
||||
import com.paypal.orders.Order;
|
||||
import com.stripe.Stripe;
|
||||
import com.stripe.exception.StripeException;
|
||||
import com.stripe.model.Charge;
|
||||
import com.stripe.model.Invoice;
|
||||
import com.stripe.model.Subscription;
|
||||
import com.stripe.model.checkout.Session;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -28,6 +30,12 @@ import java.util.Objects;
|
||||
@Slf4j
|
||||
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
|
||||
|
||||
private final StripeServiceImpl stripeServiceImpl;
|
||||
|
||||
public PaymentInfoServiceImpl(StripeServiceImpl stripeServiceImpl) {
|
||||
this.stripeServiceImpl = stripeServiceImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录支付日志:微信支付
|
||||
* @param plainText
|
||||
@@ -152,7 +160,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
baseMapper.insert(paymentInfo);
|
||||
}
|
||||
|
||||
public void createPaymentInfoForStripe(Session session){
|
||||
public void createOrUpdatePaymentInfoForStripe(Session session){
|
||||
String orderId = session.getMetadata().get("orderId");
|
||||
String status = session.getStatus();
|
||||
// 获取transactionId,从sessionId更改为invoiceId
|
||||
@@ -176,7 +184,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
|
||||
@Value("${stripe.private-key}")
|
||||
private String privateKey;
|
||||
public PaymentInfo createPaymentInfoForStripe(Invoice invoice){
|
||||
public PaymentInfo createOrUpdatePaymentInfoForStripe(Invoice invoice){
|
||||
Stripe.apiKey = privateKey;
|
||||
// 获取transactionId,从sessionId更改为invoiceId
|
||||
String invoiceId = invoice.getId();
|
||||
@@ -184,6 +192,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("transaction_id", invoiceId);
|
||||
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
|
||||
String status = invoice.getStatus();
|
||||
// 判断当前支付是否已经被记录,确保同一个支付不会被重复记录
|
||||
if (Objects.isNull(paymentInfo)){
|
||||
String orderNo;
|
||||
@@ -199,13 +208,19 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String status = invoice.getStatus();
|
||||
Long amountTotal = invoice.getAmountPaid();
|
||||
Long amountTotal;
|
||||
if (status.equals("paid")){
|
||||
amountTotal = invoice.getAmountPaid();
|
||||
}else {
|
||||
amountTotal = invoice.getAmountDue();
|
||||
}
|
||||
|
||||
// stripe 的支付金额单位是分,在我们数据库中金额单位为 元
|
||||
Float divide = new BigDecimal(amountTotal).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).floatValue();
|
||||
String type = invoice.getBillingReason().equals("subscription_create") ? "new" :
|
||||
invoice.getBillingReason().equals("subscription_cycle") ? "renewal" : invoice.getBillingReason();
|
||||
|
||||
Map<String, String> paymentMethod = stripeServiceImpl.getPaymentMethodByInvoiceId(invoiceId);
|
||||
|
||||
paymentInfo = new PaymentInfo();
|
||||
paymentInfo.setOrderNo(orderNo);
|
||||
@@ -219,12 +234,84 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setContent(json);
|
||||
paymentInfo.setType(type);
|
||||
paymentInfo.setNotified(0);
|
||||
paymentInfo.setPaymentMethod(paymentMethod.get("paymentMethod"));
|
||||
paymentInfo.setLast4(paymentMethod.get("last4"));
|
||||
paymentInfo.setCreateTime(LocalDateTime.now());
|
||||
|
||||
baseMapper.insert(paymentInfo);
|
||||
}else {
|
||||
paymentInfo.setTradeState(status);
|
||||
paymentInfo.setUpdateTime(LocalDateTime.now());
|
||||
baseMapper.updateById(paymentInfo);
|
||||
}
|
||||
return paymentInfo;
|
||||
}
|
||||
|
||||
public PaymentInfo createOrUpdatePaymentInfoForStripe(Charge charge){
|
||||
Stripe.apiKey = privateKey;
|
||||
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("transaction_id", charge.getInvoice());
|
||||
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
|
||||
Charge.PaymentMethodDetails paymentMethodDetails = charge.getPaymentMethodDetails();
|
||||
String paymentMethod;
|
||||
String last4 = "N/A";
|
||||
switch (paymentMethodDetails.getType()){
|
||||
case "alipay":
|
||||
paymentMethod = "Alipay";
|
||||
break;
|
||||
case "bancontact":
|
||||
paymentMethod = "BanContact";
|
||||
break;
|
||||
case "card":
|
||||
Charge.PaymentMethodDetails.Card card = paymentMethodDetails.getCard();
|
||||
String brand = card.getBrand();
|
||||
brand = brand.substring(0, 1).toUpperCase() + brand.substring(1);
|
||||
paymentMethod = brand + " " + card.getFunding() + "card";
|
||||
last4 = card.getLast4();
|
||||
break;
|
||||
case "eps":
|
||||
Charge.PaymentMethodDetails.Eps eps = paymentMethodDetails.getEps();
|
||||
paymentMethod = eps.getBank();
|
||||
break;
|
||||
case "giropay":
|
||||
paymentMethod = "GiroPay";
|
||||
break;
|
||||
case "ideal":
|
||||
Charge.PaymentMethodDetails.Ideal ideal = paymentMethodDetails.getIdeal();
|
||||
paymentMethod = ideal.getBank();
|
||||
break;
|
||||
case "link":
|
||||
paymentMethod = "Link";
|
||||
break;
|
||||
default:
|
||||
paymentMethod = "N/A";
|
||||
}
|
||||
if (Objects.isNull(paymentInfo)){
|
||||
Stripe.apiKey = privateKey;
|
||||
|
||||
Float divide = new BigDecimal(charge.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).floatValue();
|
||||
paymentInfo = new PaymentInfo();
|
||||
paymentInfo.setOrderNo(charge.getDescription().replace("AiDA - ", ""));
|
||||
paymentInfo.setTransactionId(charge.getInvoice());
|
||||
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
||||
paymentInfo.setTradeState(charge.getStatus());
|
||||
paymentInfo.setPayerTotal(divide);
|
||||
paymentInfo.setNotified(0);
|
||||
paymentInfo.setPaymentMethod(paymentMethod);
|
||||
paymentInfo.setLast4(last4);
|
||||
paymentInfo.setCreateTime(LocalDateTime.now());
|
||||
baseMapper.insert(paymentInfo);
|
||||
}else {
|
||||
paymentInfo.setTradeState(charge.getStatus());
|
||||
paymentInfo.setPaymentMethod(paymentMethod);
|
||||
paymentInfo.setLast4(last4);
|
||||
paymentInfo.setUpdateTime(LocalDateTime.now());
|
||||
baseMapper.updateById(paymentInfo);
|
||||
}
|
||||
|
||||
return paymentInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PaymentInfo getPaymentInfoByOrderId(String orderId){
|
||||
|
||||
@@ -271,6 +271,10 @@ public class StripeServiceImpl implements StripeService {
|
||||
Session session = (Session) stripeObject;
|
||||
if (event.getType().equals("checkout.session.completed")) {
|
||||
processOrder(session);
|
||||
}else if (event.getType().equals("checkout.session.expired")){
|
||||
String orderNo = session.getMetadata().get("orderId");
|
||||
// 会话过期 未支付 且之后没有支付成功的订单
|
||||
processExpiredOrder(orderNo);
|
||||
}
|
||||
} else if (stripeObject instanceof Subscription){
|
||||
Subscription subscription = (Subscription) stripeObject;
|
||||
@@ -280,25 +284,30 @@ public class StripeServiceImpl implements StripeService {
|
||||
log.info("创建连续订阅");
|
||||
} else if (event.getType().equals("customer.subscription.updated")){
|
||||
// 更新订阅信息
|
||||
response = updateSubscription(subscription);
|
||||
updateSubscription(subscription);
|
||||
log.info("订阅更新");
|
||||
if (subscription.getStatus().equals("active")){
|
||||
response = sendEmail(subscription.getId(), null);
|
||||
}
|
||||
} else if (event.getType().equals("customer.subscription.deleted")){
|
||||
response = updateSubscription(subscription);
|
||||
SubscriptionInfo subscriptionInfo = updateSubscription(subscription);
|
||||
log.info("用户取消连续订阅");
|
||||
} else if (event.getType().equals("customer.subscription.paused")){
|
||||
if (subscriptionInfo.getCancelNotified() == (byte)0){
|
||||
response = sendEmail(subscription.getId(), "cancel");
|
||||
}
|
||||
subscriptionInfo.setCancelNotified((byte)1);
|
||||
subscriptionInfoMapper.updateById(subscriptionInfo);
|
||||
}/* else if (event.getType().equals("customer.subscription.paused")){
|
||||
updateSubscription(subscription);
|
||||
} else if (event.getType().equals("customer.subscription.resumed")){
|
||||
updateSubscription(subscription);
|
||||
log.info("用户订阅恢复");
|
||||
}
|
||||
}*/
|
||||
} else if (stripeObject instanceof Invoice) {
|
||||
Invoice invoice = (Invoice) stripeObject;
|
||||
if (event.getType().equals("invoice.paid")) {
|
||||
// 新增支付成功的信息,返回orderNo,表示,该回调第一次被记录
|
||||
PaymentInfo paymentInfo = paymentInfoService.createPaymentInfoForStripe(invoice);
|
||||
PaymentInfo paymentInfo = paymentInfoService.createOrUpdatePaymentInfoForStripe(invoice);
|
||||
|
||||
// 当前支付没有被通知时才需要发送通知邮件
|
||||
if (paymentInfo.getNotified().equals(0)) {
|
||||
@@ -311,6 +320,43 @@ public class StripeServiceImpl implements StripeService {
|
||||
response = sendEmail(invoice.getSubscription(), "renewal");
|
||||
}
|
||||
}
|
||||
} else if (event.getType().equals("invoice.payment_failed")) {
|
||||
// 更新支付信息
|
||||
QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("transaction_id", invoice.getId());
|
||||
PaymentInfo paymentInfo = paymentInfoService.getBaseMapper().selectOne(queryWrapper);
|
||||
if (!Objects.isNull(paymentInfo)){
|
||||
String type = invoice.getBillingReason().equals("subscription_create") ? "new" :
|
||||
invoice.getBillingReason().equals("subscription_cycle") ? "renewal" : invoice.getBillingReason();
|
||||
Gson gson = new Gson();
|
||||
String json = gson.toJson(invoice);
|
||||
paymentInfo.setContent(json);
|
||||
paymentInfo.setType(type);
|
||||
paymentInfoService.updateById(paymentInfo);
|
||||
}
|
||||
/*// 支付失败 通知商家的条件 1、会话过期 2、支付失败 3、这个用户在这个支付失败后再无支付成功的订阅
|
||||
if (invoice.getBillingReason().equals("subscription_create")){
|
||||
response = sendEmail(paymentInfo.getOrderNo());
|
||||
} else if (invoice.getBillingReason().equals("subscription_cycle")){
|
||||
response = sendEmail(invoice.getSubscription(), "fail_renewal");
|
||||
}*/
|
||||
}
|
||||
}else if (stripeObject instanceof Charge) {
|
||||
Charge charge = (Charge) stripeObject;
|
||||
String orderNo = charge.getDescription().replace("AiDA - ", "");
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||
if (event.getType().equals("charge.failed")){
|
||||
// 添加支付信息 && 更新支付信息
|
||||
// 支付失败时,无法通过invoice_id获取支付方式,所以使用charge.failed回调添加支付信息
|
||||
paymentInfoService.createOrUpdatePaymentInfoForStripe(charge);
|
||||
|
||||
orderInfo.setOrderStatus(OrderStatusEnum.FAILURE.getType());
|
||||
orderInfo.setNote(charge.getFailureMessage());
|
||||
orderInfoService.updateById(orderInfo);
|
||||
}else if (event.getType().equals("charge.succeeded")){
|
||||
orderInfo.setOrderStatus(OrderStatusEnum.SUCCESS.getType());
|
||||
orderInfo.setNote("");
|
||||
orderInfoService.updateById(orderInfo);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
@@ -351,6 +397,36 @@ public class StripeServiceImpl implements StripeService {
|
||||
}
|
||||
}
|
||||
|
||||
private void processExpiredOrder(String orderNo) {
|
||||
// 支付失败 通知商家的条件 1、会话过期 2、支付失败 3、这个用户在这个支付失败后再无支付成功的订阅
|
||||
// 1、获取当前订单的支付状态
|
||||
// String orderNo = session.getMetadata().get("orderId");
|
||||
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||
// 2、确认订单状态为支付失败
|
||||
if (orderByOrderNo.getOrderStatus().equals(OrderStatusEnum.FAILURE.getType())) {
|
||||
// 3、判断失败订单之后再无成功的订单
|
||||
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("account_id", orderByOrderNo.getAccountId());
|
||||
queryWrapper.gt("create_time", orderByOrderNo.getCreateTime());
|
||||
queryWrapper.eq("order_status", OrderStatusEnum.SUCCESS.getType());
|
||||
queryWrapper.likeLeft("title", "Subscription");
|
||||
List<OrderInfo> orderInfos = orderInfoService.getBaseMapper().selectList(queryWrapper);
|
||||
if (orderInfos.isEmpty()) {
|
||||
// 4、判断当前订单有没有订阅信息
|
||||
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("order_no", orderNo);
|
||||
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
|
||||
// 发送邮件通知商家用户支付失败
|
||||
if (Objects.isNull(subscriptionInfo) || subscriptionInfo.getStatus().equals("incomplete")) {
|
||||
sendEmail(orderNo);
|
||||
}else {
|
||||
sendEmail(subscriptionInfo.getSubscriptionId(), "fail_renewal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SubscriptionInfo createSubscription(Subscription subscription){
|
||||
// 确认当前subscription是否已经记录
|
||||
@@ -366,7 +442,6 @@ public class StripeServiceImpl implements StripeService {
|
||||
// 从回调信息中获取recurring type
|
||||
SubscriptionItem subscriptionItem = subscription.getItems().getData().get(0);
|
||||
String interval = subscriptionItem.getPrice().getRecurring().getInterval();
|
||||
Map<String, String> paymentMethod = getPaymentMethodByInvoiceId(subscription.getLatestInvoice());
|
||||
|
||||
subscriptionInfo = new SubscriptionInfo();
|
||||
subscriptionInfo.setAccountId(orderInfo.getAccountId());
|
||||
@@ -374,8 +449,6 @@ public class StripeServiceImpl implements StripeService {
|
||||
subscriptionInfo.setSubscriptionId(subscription.getId());
|
||||
subscriptionInfo.setType(interval);
|
||||
subscriptionInfo.setStatus(subscription.getStatus());
|
||||
subscriptionInfo.setPaymentMethod(paymentMethod.get("paymentMethod"));
|
||||
subscriptionInfo.setLast4(paymentMethod.get("last4"));
|
||||
subscriptionInfo.setNextPayDate(changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
|
||||
subscriptionInfo.setCurrentPeriodStart(subscription.getCurrentPeriodStart());
|
||||
subscriptionInfo.setCurrentPeriodEnd(subscription.getCurrentPeriodEnd());
|
||||
@@ -406,7 +479,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean updateSubscription(Subscription subscription){
|
||||
public SubscriptionInfo updateSubscription(Subscription subscription){
|
||||
// 获取当前是否有已经记录的subscriptionInfo
|
||||
SubscriptionInfo subscriptionInfo = createSubscription(subscription);
|
||||
// 用于标志数据有没有变动,避免在没有改动的情况下频繁的更新数据库
|
||||
@@ -415,9 +488,6 @@ public class StripeServiceImpl implements StripeService {
|
||||
subscriptionInfo.setStatus(subscription.getStatus());
|
||||
flag = true;
|
||||
}
|
||||
if (subscription.getStatus().equals("canceled")){
|
||||
subscriptionInfo.setAutoRenewal((byte) 0);
|
||||
}
|
||||
if (!subscriptionInfo.getCurrentPeriodStart().equals(subscription.getCurrentPeriodStart())){
|
||||
subscriptionInfo.setCurrentPeriodStart(subscription.getCurrentPeriodStart());
|
||||
flag = true;
|
||||
@@ -432,10 +502,9 @@ public class StripeServiceImpl implements StripeService {
|
||||
}
|
||||
if (flag){
|
||||
subscriptionInfo.setUpdateTime(LocalDateTime.now());
|
||||
// todo 这里需要再检查支付方式吗?
|
||||
subscriptionInfoMapper.updateById(subscriptionInfo);
|
||||
}
|
||||
return true;
|
||||
return subscriptionInfo;
|
||||
}
|
||||
|
||||
private void updateAccountValidity(Long accountId, Long currentPeriodEnd){
|
||||
@@ -633,6 +702,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
switch (retrieve.getType()){
|
||||
case "alipay":
|
||||
paymentMethod = "Alipay";
|
||||
last4 = "N/A";
|
||||
break;
|
||||
case "bancontact":
|
||||
paymentMethod = "BanContact";
|
||||
@@ -647,17 +717,24 @@ public class StripeServiceImpl implements StripeService {
|
||||
case "eps":
|
||||
PaymentMethod.Eps eps = retrieve.getEps();
|
||||
paymentMethod = eps.getBank();
|
||||
last4 = "N/A";
|
||||
break;
|
||||
case "giropay":
|
||||
paymentMethod = "GiroPay";
|
||||
last4 = "N/A";
|
||||
break;
|
||||
case "ideal":
|
||||
PaymentMethod.Ideal ideal = retrieve.getIdeal();
|
||||
paymentMethod = ideal.getBank();
|
||||
last4 = "N/A";
|
||||
break;
|
||||
case "link":
|
||||
paymentMethod = "Link";
|
||||
last4 = "N/A";
|
||||
break;
|
||||
default:
|
||||
paymentMethod = "N/A";
|
||||
last4 = "N/A";
|
||||
}
|
||||
HashMap<String, String> resp = new HashMap<>();
|
||||
resp.put("paymentMethod", paymentMethod);
|
||||
@@ -669,7 +746,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
// return null;
|
||||
}
|
||||
|
||||
public boolean sendEmail(String subscriptionId, String type){
|
||||
public boolean sendEmail(String subscriptionId, String type) {
|
||||
|
||||
SubscriptionEmailParamsDTO emailParamsDTO = new SubscriptionEmailParamsDTO();
|
||||
QueryWrapper<SubscriptionInfo> qwSI = new QueryWrapper<>();
|
||||
@@ -688,9 +765,9 @@ public class StripeServiceImpl implements StripeService {
|
||||
if (StringUtil.isNullOrEmpty(type)){
|
||||
// 如果没有传入type,则使用paymentInfo中记录的类型
|
||||
// (其实这里也可以通过invoiceId查询stripe,但是记录在自己的db中可以不用每次都查,且方便查看)
|
||||
type = paymentInfo.getType();
|
||||
type = StringUtil.isNullOrEmpty(paymentInfo.getType()) ? "new" : paymentInfo.getType();
|
||||
}
|
||||
if (!type.equals("reminder") && paymentInfo.getNotified() == 1){
|
||||
if (!type.equals("reminder") && !type.equals("cancel") && paymentInfo.getNotified() == 1){
|
||||
// 已经邮件通知过,直接返回
|
||||
return true;
|
||||
}
|
||||
@@ -707,8 +784,10 @@ public class StripeServiceImpl implements StripeService {
|
||||
emailParamsDTO.setTotalFee(paymentInfo.getPayerTotal().toString());
|
||||
emailParamsDTO.setLastOrderDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodStart(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
|
||||
emailParamsDTO.setEndOfPrepaidTerm(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
|
||||
emailParamsDTO.setPaymentMethod(subscriptionInfo.getPaymentMethod());
|
||||
emailParamsDTO.setPaymentMethod(paymentInfo.getPaymentMethod());
|
||||
emailParamsDTO.setLast4(paymentInfo.getLast4());
|
||||
emailParamsDTO.setSubscriptionId(subscriptionInfo.getId().toString());
|
||||
emailParamsDTO.setFailMessage(orderByOrderNo.getNote());
|
||||
emailParamsDTO.setSubscriptionType(subscriptionInfo.getType());
|
||||
emailParamsDTO.setStartDate(changeTimeStampFormat(orderByOrderNo.getCreateTime()));
|
||||
emailParamsDTO.setNextPayDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
|
||||
@@ -717,7 +796,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||
|
||||
// 邮件通知成功后,更新标志
|
||||
if (!type.equals("reminder")){
|
||||
if (!type.equals("reminder") && !type.equals("cancel")){
|
||||
PaymentInfo payment = new PaymentInfo();
|
||||
payment.setId(paymentInfo.getId());
|
||||
payment.setNotified(1);
|
||||
@@ -727,6 +806,40 @@ public class StripeServiceImpl implements StripeService {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean sendEmail(String orderNo){
|
||||
SubscriptionEmailParamsDTO emailParamsDTO = new SubscriptionEmailParamsDTO();
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||
|
||||
com.ai.da.mapper.primary.entity.Account account = accountMapper.selectById(orderInfo.getAccountId());
|
||||
String userName = account.getUserName();
|
||||
String language = account.getLanguage();
|
||||
QueryWrapper<PaymentInfo> qwPI = new QueryWrapper<>();
|
||||
qwPI.eq("order_no", orderNo);
|
||||
List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qwPI);
|
||||
if (paymentInfos.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
PaymentInfo paymentInfo = paymentInfos.get(0);
|
||||
emailParamsDTO.setUsername(userName);
|
||||
emailParamsDTO.setOrderId(paymentInfo.getId().toString());
|
||||
emailParamsDTO.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
|
||||
emailParamsDTO.setQuantity(String.valueOf(1));
|
||||
emailParamsDTO.setTotalFee(paymentInfo.getPayerTotal().toString());
|
||||
emailParamsDTO.setFailMessage(orderInfo.getNote());
|
||||
emailParamsDTO.setPaymentMethod(paymentInfo.getPaymentMethod());
|
||||
emailParamsDTO.setLast4(paymentInfo.getLast4());
|
||||
|
||||
SendEmailUtil.subscriptionEmailReminder("fail_new", emailParamsDTO, language, account.getUserEmail());
|
||||
|
||||
// 邮件通知成功后,更新标志
|
||||
PaymentInfo payment = new PaymentInfo();
|
||||
payment.setId(paymentInfo.getId());
|
||||
payment.setNotified(1);
|
||||
payment.setUpdateTime(LocalDateTime.now());
|
||||
paymentInfoMapper.updateById(payment);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void subscriptionReminder(){
|
||||
// 提前7天的 00:00:00 和 23:59:59
|
||||
LocalDateTime startOfDay = LocalDateTime.now().plusDays(7).toLocalDate().atStartOfDay();
|
||||
|
||||
Reference in New Issue
Block a user