支付优化-续订失败邮件通知
This commit is contained in:
@@ -236,6 +236,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setNotified(0);
|
||||
paymentInfo.setPaymentMethod(paymentMethod.get("paymentMethod"));
|
||||
paymentInfo.setLast4(paymentMethod.get("last4"));
|
||||
paymentInfo.setHostedInvoiceUrl(invoice.getHostedInvoiceUrl());
|
||||
paymentInfo.setCreateTime(LocalDateTime.now());
|
||||
|
||||
baseMapper.insert(paymentInfo);
|
||||
|
||||
@@ -284,19 +284,27 @@ public class StripeServiceImpl implements StripeService {
|
||||
log.info("创建连续订阅");
|
||||
} else if (event.getType().equals("customer.subscription.updated")){
|
||||
// 更新订阅信息
|
||||
updateSubscription(subscription);
|
||||
SubscriptionInfo subscriptionInfo = updateSubscription(subscription);
|
||||
log.info("订阅更新");
|
||||
if (subscription.getStatus().equals("active")){
|
||||
response = sendEmail(subscription.getId(), null);
|
||||
}
|
||||
// 续订支付失败,邮件通知用户
|
||||
if (subscription.getStatus().equals("past_due")){
|
||||
// 发送续订失败邮件
|
||||
response = sendRenewalFailEmail(null, subscription.getId(), subscriptionInfo.getOrderNo());
|
||||
|
||||
}
|
||||
} else if (event.getType().equals("customer.subscription.deleted")){
|
||||
SubscriptionInfo subscriptionInfo = updateSubscription(subscription);
|
||||
log.info("用户取消连续订阅");
|
||||
log.info("用户 {} 取消连续订阅 {}", subscriptionInfo.getAccountId(), subscription.getId());
|
||||
if (subscriptionInfo.getCancelNotified() == (byte)0){
|
||||
log.info("取消订阅 邮件通知商家");
|
||||
response = sendEmail(subscription.getId(), "cancel");
|
||||
subscriptionInfo.setCancelNotified((byte)1);
|
||||
subscriptionInfoMapper.updateById(subscriptionInfo);
|
||||
}
|
||||
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")){
|
||||
@@ -332,14 +340,13 @@ public class StripeServiceImpl implements StripeService {
|
||||
String json = gson.toJson(invoice);
|
||||
paymentInfo.setContent(json);
|
||||
paymentInfo.setType(type);
|
||||
paymentInfo.setHostedInvoiceUrl(invoice.getHostedInvoiceUrl());
|
||||
paymentInfoService.updateById(paymentInfo);
|
||||
|
||||
// 发送续订失败邮件
|
||||
response = sendRenewalFailEmail(invoice.getId(), null, paymentInfo.getOrderNo());
|
||||
}
|
||||
/*// 支付失败 通知商家的条件 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;
|
||||
@@ -417,9 +424,12 @@ public class StripeServiceImpl implements StripeService {
|
||||
qw.eq("order_no", orderNo);
|
||||
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
|
||||
// 发送邮件通知商家用户支付失败
|
||||
if (Objects.isNull(subscriptionInfo) || subscriptionInfo.getStatus().equals("incomplete")) {
|
||||
if (Objects.isNull(subscriptionInfo)
|
||||
|| subscriptionInfo.getStatus().equals("incomplete")
|
||||
|| subscriptionInfo.getStatus().equals("incomplete_expired")) {
|
||||
sendEmail(orderNo);
|
||||
}else {
|
||||
// todo 续订失败 应该不会走这里
|
||||
sendEmail(subscriptionInfo.getSubscriptionId(), "fail_renewal");
|
||||
}
|
||||
}
|
||||
@@ -535,6 +545,18 @@ public class StripeServiceImpl implements StripeService {
|
||||
});
|
||||
}
|
||||
|
||||
public void cancelSubscriptionTemp(String subscriptionId) {
|
||||
Stripe.apiKey = privateKey;
|
||||
try {
|
||||
log.info("申请取消连续订阅 {}", subscriptionId);
|
||||
Subscription subscription = Subscription.retrieve(subscriptionId);
|
||||
Subscription cancel = subscription.cancel();
|
||||
cancel.getStatus();
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String refund(String amount, String orderNo, String reason) {
|
||||
Refund refund;
|
||||
RefundInfo refundByOrderNo = refundInfoService.createRefundByOrderNo(orderNo, reason);
|
||||
@@ -630,7 +652,6 @@ public class StripeServiceImpl implements StripeService {
|
||||
|
||||
}
|
||||
|
||||
// 获取所有订阅
|
||||
public List<Subscription> getSubscription(String username, String userEmail) {
|
||||
Stripe.apiKey = privateKey;
|
||||
String customerId = null;
|
||||
@@ -642,6 +663,25 @@ public class StripeServiceImpl implements StripeService {
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取所有订阅
|
||||
public List<String> getSubscriptionIds(String username, String userEmail) {
|
||||
Stripe.apiKey = privateKey;
|
||||
String customerId = null;
|
||||
try {
|
||||
customerId = getCustomer(username, userEmail);
|
||||
SubscriptionCollection list = Subscription.list(SubscriptionListParams.builder()
|
||||
.setCustomer(customerId).build());
|
||||
List<Subscription> data = list.getData();
|
||||
ArrayList<String> subscriptionIds = new ArrayList<>();
|
||||
data.forEach(subscription -> {
|
||||
subscriptionIds.add(subscription.getId());
|
||||
});
|
||||
return subscriptionIds;
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -747,7 +787,6 @@ public class StripeServiceImpl implements StripeService {
|
||||
}
|
||||
|
||||
public boolean sendEmail(String subscriptionId, String type) {
|
||||
|
||||
SubscriptionEmailParamsDTO emailParamsDTO = new SubscriptionEmailParamsDTO();
|
||||
QueryWrapper<SubscriptionInfo> qwSI = new QueryWrapper<>();
|
||||
qwSI.eq("subscription_id", subscriptionId);
|
||||
@@ -784,14 +823,7 @@ 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(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));
|
||||
emailParamsDTO.setRenewalTime(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
|
||||
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO);
|
||||
|
||||
SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
|
||||
|
||||
@@ -840,6 +872,79 @@ public class StripeServiceImpl implements StripeService {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean sendRenewalFailEmail(String invoiceId, String subscriptionId, String orderNo){
|
||||
// 1、确认当前订单最后一笔支付为fail
|
||||
// 更新支付信息
|
||||
PaymentInfo paymentInfo;
|
||||
QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
|
||||
if (StringUtil.isNullOrEmpty(invoiceId)){
|
||||
queryWrapper.eq("order_no", orderNo).orderByDesc("id");
|
||||
List<PaymentInfo> paymentInfos = paymentInfoService.getBaseMapper().selectList(queryWrapper);
|
||||
if (paymentInfos.isEmpty() || !paymentInfos.get(0).getTradeState().equals("failed")){
|
||||
return false;
|
||||
}else {
|
||||
paymentInfo = paymentInfos.get(0);
|
||||
}
|
||||
}else {
|
||||
queryWrapper.eq("transaction_id", invoiceId);
|
||||
paymentInfo = paymentInfoService.getBaseMapper().selectOne(queryWrapper);
|
||||
if (Objects.isNull(paymentInfo)
|
||||
|| !paymentInfo.getTradeState().equals("failed")
|
||||
|| paymentInfo.getNotified().equals(1)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 2、确认当前订阅的状态为past_due
|
||||
SubscriptionInfo subscriptionInfo;
|
||||
QueryWrapper<SubscriptionInfo> qwSI = new QueryWrapper<>();
|
||||
if (StringUtil.isNullOrEmpty(subscriptionId)){
|
||||
qwSI.eq("order_no", orderNo);
|
||||
}else {
|
||||
qwSI.eq("subscription_id", subscriptionId);
|
||||
}
|
||||
subscriptionInfo = subscriptionInfoMapper.selectOne(qwSI);
|
||||
if (Objects.isNull(subscriptionInfo) || !subscriptionInfo.getStatus().equals("past_due")){
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3、组参数
|
||||
com.ai.da.mapper.primary.entity.Account account = accountMapper.selectById(subscriptionInfo.getAccountId());
|
||||
String userName = account.getUserName();
|
||||
String language = account.getLanguage();
|
||||
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(subscriptionInfo.getOrderNo());
|
||||
SubscriptionEmailParamsDTO emailParamsDTO = new SubscriptionEmailParamsDTO();
|
||||
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());
|
||||
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO);
|
||||
// todo
|
||||
emailParamsDTO.setAccountPageRef("\"https://www.aida.com.hk/home/homePage\"");
|
||||
|
||||
// 4、发邮件
|
||||
SendEmailUtil.subscriptionEmailReminder("fail_renewal", emailParamsDTO, language, account.getUserEmail());
|
||||
|
||||
PaymentInfo payment = new PaymentInfo();
|
||||
payment.setId(paymentInfo.getId());
|
||||
payment.setNotified(1);
|
||||
payment.setUpdateTime(LocalDateTime.now());
|
||||
paymentInfoMapper.updateById(payment);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setSubscriptionParams(PaymentInfo paymentInfo, SubscriptionInfo subscriptionInfo, OrderInfo orderByOrderNo, SubscriptionEmailParamsDTO emailParamsDTO) {
|
||||
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));
|
||||
emailParamsDTO.setRenewalTime(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
|
||||
}
|
||||
|
||||
public void subscriptionReminder(){
|
||||
// 提前7天的 00:00:00 和 23:59:59
|
||||
LocalDateTime startOfDay = LocalDateTime.now().plusDays(7).toLocalDate().atStartOfDay();
|
||||
@@ -876,4 +981,87 @@ public class StripeServiceImpl implements StripeService {
|
||||
}
|
||||
}
|
||||
|
||||
// todo 新建一个订阅 使用不会成功的付款方式
|
||||
|
||||
public String createSubscriptionTemp(String name, String email){
|
||||
Stripe.apiKey = privateKey;
|
||||
try {
|
||||
OrderInfo orderInfo = orderInfoService.createOrderByProductId(1, PayTypeEnum.STRIPE.getType(), ProductEnum.DailySubscription);
|
||||
|
||||
String paymentMethodCode = "pm_card_mastercard";
|
||||
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodCode);
|
||||
|
||||
String customerId = getCustomer(name, email);
|
||||
log.info("customerId: {}", customerId);
|
||||
|
||||
PaymentMethodAttachParams attachParams = PaymentMethodAttachParams.builder()
|
||||
.setCustomer(customerId)
|
||||
.build();
|
||||
paymentMethod.attach(attachParams);
|
||||
|
||||
// 设置默认付款方式
|
||||
Customer updatedCustomer = Customer.retrieve(customerId);
|
||||
CustomerUpdateParams params = CustomerUpdateParams.builder()
|
||||
.setInvoiceSettings(
|
||||
CustomerUpdateParams.InvoiceSettings.builder()
|
||||
.setDefaultPaymentMethod(paymentMethod.getId())
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
updatedCustomer.update(params);
|
||||
|
||||
// 3. 创建订阅
|
||||
SubscriptionCreateParams subscriptionParams = SubscriptionCreateParams.builder()
|
||||
.setCustomer(customerId)
|
||||
.addItem(
|
||||
SubscriptionCreateParams.Item.builder()
|
||||
.setPrice("price_1QFXkf02n1TEydyNtA4TQ3Yz") // 替换为实际的价格 ID
|
||||
.build()
|
||||
)
|
||||
.setDescription("AiDA - " + orderInfo.getOrderNo())
|
||||
.build();
|
||||
Subscription subscription = Subscription.create(subscriptionParams);
|
||||
|
||||
// 打印订阅 ID
|
||||
System.out.println("Subscription created: " + subscription.getId());
|
||||
return subscription.getId();
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String changeCustomerPayment(String name, String email){
|
||||
Stripe.apiKey = privateKey;
|
||||
String paymentMethodCode = "pm_card_chargeCustomerFail";
|
||||
try {
|
||||
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodCode);
|
||||
|
||||
String customerId = getCustomer(name, email);
|
||||
log.info("customerId: {}", customerId);
|
||||
|
||||
// 附加支付方式到客户
|
||||
PaymentMethodAttachParams attachParams = PaymentMethodAttachParams.builder()
|
||||
.setCustomer(customerId)
|
||||
.build();
|
||||
paymentMethod.attach(attachParams);
|
||||
// 更新客户的默认支付方式
|
||||
CustomerUpdateParams params = CustomerUpdateParams.builder()
|
||||
.setInvoiceSettings(
|
||||
CustomerUpdateParams.InvoiceSettings.builder()
|
||||
.setDefaultPaymentMethod(paymentMethod.getId())
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
// 更新客户信息
|
||||
Customer customer = Customer.retrieve(customerId);
|
||||
customer.update(params);
|
||||
|
||||
return paymentMethod.getId();
|
||||
|
||||
} catch (StripeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user