Affiliate功能-数据库表设计更新

This commit is contained in:
2024-12-18 11:53:41 +08:00
parent bf8af41f3f
commit 7d8f047087
16 changed files with 338 additions and 72 deletions

View File

@@ -2,16 +2,14 @@ package com.ai.da.common.task;
import com.ai.da.common.enums.PayTypeEnum;
import com.ai.da.mapper.primary.entity.OrderInfo;
import com.ai.da.service.AliPayService;
import com.ai.da.service.OrderInfoService;
import com.ai.da.service.PayPalCheckoutService;
import com.ai.da.service.StripeService;
import com.ai.da.service.*;
import com.paypal.http.exceptions.SerializeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;
@Slf4j
@@ -24,6 +22,10 @@ public class PaymentTask {
@Resource
private StripeService stripeService;
@Resource
private AffiliateService affiliateService;
// 考虑删除该定时任务(原因:之后的订单列允许用户查看发票,发票未过期时仍可以支付,所以不需要手动使订单过期)
// @Scheduled(cron = "0/30 * * * * ?")
public void orderConfirmForStripe() throws SerializeException {
@@ -89,8 +91,31 @@ public class PaymentTask {
}
// 每天凌晨检查subscription中有哪些已过期更新状态
@Scheduled(cron = "0 0 0 * * ?")
public void checkSubscriptionExpiration(){
stripeService.checkSubscriptionExpiration();
// @Scheduled(cron = "0 0 0 * * ?")
// public void checkSubscriptionExpiration(){
// stripeService.checkSubscriptionExpiration();
// }
// 如果有订阅已创建,但是没有发邮件通知的,需要主动获取回调信息并向用户发送邮件
public void checkSubscriptionPayment(){
//
}
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
public void updateAffiliateInfoWithPayment(){
affiliateService.updateAffiliateInfoWithPayment();
}
@Scheduled(cron = "0 0 8 28-31 * ?")
public void commissionSummaryReminder(){
// 每个月末的最后一天的早上八点执行
LocalDate today = LocalDate.now();
// 判断是否为月底
if (today.plusDays(1).getDayOfMonth() == 1) {
log.info("今天是月底,执行佣金结算提醒任务!");
affiliateService.commissionCalculation(null, null);
}
}
}

View File

@@ -279,7 +279,7 @@ public class RedisUtil {
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
}
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime:";
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";

View File

@@ -28,7 +28,7 @@ public class AffiliateController {
@ApiOperation(value = "注册成为affiliate")
@GetMapping("/registration")
public Response<Boolean> completeGuidance(@RequestParam("promotionMethod") String promotionMethod) {
public Response<Boolean> completeGuidance(@RequestParam(value = "promotionMethod", required = false) String promotionMethod) {
return Response.success(affiliateService.registerAsAnAffiliate(promotionMethod));
}
@@ -44,18 +44,31 @@ public class AffiliateController {
return Response.success(affiliateService.personalAffiliateCenter());
}
@ApiOperation(value = "获取个人佣金图表数据")
@GetMapping("/getPersonalMonthlyIncome")
public Response<double[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
return Response.success(affiliateService.getPersonalMonthlyIncome(year));
}
@ApiOperation(value = "审批affiliate申请")
@GetMapping("/approval")
public Response<Boolean> applicationApproval(@RequestParam("id") Long id, @RequestParam("isApproved")Boolean isApproved) {
return Response.success(affiliateService.applicationApproval(id, isApproved));
}
@ApiOperation(value = "定时计算佣金")
/*@ApiOperation(value = "定时计算佣金")
@GetMapping("/testTask")
public Response<String> testTask() {
affiliateService.updateAffiliateInfoWithPayment();
return Response.success("success ");
}
}*/
/*@ApiOperation(value = "每月发送结算邮件")
@GetMapping("/commissionCalculation")
public Response<String> commissionCalculation() {
affiliateService.commissionCalculation(null, null);
return Response.success("success ");
}*/
@ApiOperation(value = "affiliate链接浏览量增加")
@GetMapping("/viewsIncrease")
@@ -64,9 +77,9 @@ public class AffiliateController {
}
@ApiOperation(value = "获取每个affiliate产生的收入")
@GetMapping("/getEachAffiliateGeneratedRevenue")
public Response<List<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestParam("id") Long id, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime) {
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(id, startTime, endTime));
@PostMapping("/getEachAffiliateGeneratedRevenue")
public Response<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) {
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO));
}

View File

@@ -19,6 +19,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@Api(tags = "Stripe模块")
@Slf4j
@@ -70,7 +71,7 @@ public class StripeController {
@ApiOperation("取消订阅")
@GetMapping("/cancelSubscription")
public Response<String> cancelSubscription(@RequestParam String subscriptionId, @RequestParam String reason) {
public Response<String> cancelSubscription(@RequestParam String subscriptionId, @RequestParam(required = false) String reason) {
stripeService.cancelSubscription(subscriptionId, reason);
return Response.success("success");
}
@@ -101,8 +102,14 @@ public class StripeController {
@ApiOperation("临时 查询指定用户绑定的付款方式")
@GetMapping("/getCustomerPaymentMethod")
public Response<String> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
public Response<List<Map<String,String>>> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.getCustomerPaymentMethod(name, email));
}
@ApiOperation("临时 解绑指定用户绑定的所有付款方式")
@GetMapping("/detachCustomerAllPaymentMethod")
public Response<String> detachCustomerAllPaymentMethod(@RequestParam String name, @RequestParam String email) {
return Response.success(stripeService.detachCustomerAllPaymentMethod(name, email));
}
}

View File

@@ -0,0 +1,14 @@
package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.AffiliateIncome;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;
import java.util.Map;
public interface AffiliateIncomeMapper extends BaseMapper<AffiliateIncome> {
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
}

View File

@@ -3,5 +3,9 @@ package com.ai.da.mapper.primary;
import com.ai.da.mapper.primary.entity.Affiliate;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.Map;
public interface AffiliateMapper extends BaseMapper<Affiliate> {
Map<String, Long> getMonthlyApprovedAffiliate(int year, int month);
}

View File

@@ -0,0 +1,26 @@
package com.ai.da.mapper.primary.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("t_affiliate_income")
public class AffiliateIncome extends BaseEntity {
private Long affiliateId;
private Long affiliateAccountId;
private Long inviteeAccountId;
private Float amount;
private LocalDateTime paymentTime;
private Float commission;
}

View File

@@ -1,6 +1,7 @@
package com.ai.da.model.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -8,6 +9,23 @@ import lombok.EqualsAndHashCode;
@Data
@ApiModel("查询affiliate列表")
public class AffiliateQueryDTO extends TimeQueryBaseDTO{
@ApiModelProperty("Active活跃 || Inactive过期 || Pending待审批 || Refused(拒绝)")
private String status;
@ApiModelProperty("推广者id")
private Long affiliateId;
@ApiModelProperty("按时间 DESC 降序 || ASC 升序")
private String order = "ASC";
@Override
public String toString() {
return "AffiliateQueryDTO{" +
"status='" + status + '\'' + ' ' +
"startTime='" + super.getStartTime() + '\'' + ' ' +
"endTime='" + super.getEndTime() + '\'' + ' ' +
"page='" + super.getPage() + '\'' + ' ' +
"size='" + super.getSize() + '\'' + ' ' +
'}';
}
}

View File

@@ -59,4 +59,7 @@ public class AccountLoginVO {
// 是否自动续订
private boolean isAutoRenewal;
// 是否是affiliate
private boolean isAffiliate = false;
}

View File

@@ -7,8 +7,6 @@ import com.ai.da.model.vo.AffiliateVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface AffiliateService extends IService<Affiliate> {
Boolean registerAsAnAffiliate(String promotionMethod);
@@ -17,11 +15,17 @@ public interface AffiliateService extends IService<Affiliate> {
AffiliateVO personalAffiliateCenter();
double[] getPersonalMonthlyIncome(int year);
Boolean applicationApproval(Long id, Boolean isApproved);
void updateAffiliateInfoWithPayment();
Boolean affiliateLinkViewsIncrease(Long id);
List<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime);
IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO);
Affiliate getByAccountId(Long accountId);
void commissionCalculation(Integer year, Integer month);
}

View File

@@ -44,5 +44,7 @@ public interface StripeService {
boolean sendRenewalFailEmail(String invoiceId, String subscriptionId, String orderNo);
String getCustomerPaymentMethod(String name, String email);
List<Map<String,String>> getCustomerPaymentMethod(String name, String email);
String detachCustomerAllPaymentMethod(String name, String email);
}

View File

@@ -107,6 +107,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
@Resource
private StripeService stripeService;
@Resource
private AffiliateService affiliateService;
@Override
@Transactional(rollbackFor = Exception.class)
public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) {
@@ -2428,6 +2431,10 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
response.setAutoRenewal(subscriptionInfo.getStatus().equals("active"));
}
Affiliate affiliate = affiliateService.getByAccountId(accountId);
if (!Objects.isNull(affiliate) && affiliate.getStatus().equals("Active")) {
response.setAffiliate(true);
}
return response;
}

View File

@@ -7,6 +7,8 @@ import com.ai.da.common.response.ResultEnum;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.common.utils.SendEmailUtil;
import com.ai.da.mapper.primary.AccountMapper;
import com.ai.da.mapper.primary.AffiliateIncomeMapper;
import com.ai.da.mapper.primary.AffiliateMapper;
import com.ai.da.mapper.primary.SubscriptionInfoMapper;
import com.ai.da.mapper.primary.entity.*;
@@ -31,9 +33,10 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
@Service
@Slf4j
@@ -51,6 +54,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
@Resource
private SubscriptionInfoMapper subscriptionInfoMapper;
@Resource
private AffiliateIncomeMapper affiliateIncomeMapper;
@Resource
private RedisUtil redisUtil;
@@ -79,10 +85,13 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
}
public IPage<Affiliate> getAffiliateList(AffiliateQueryDTO affiliateQueryDTO){
log.info("parameter => {}", affiliateQueryDTO.toString());
QueryWrapper<Affiliate> qw = new QueryWrapper<>();
qw.eq(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStatus()), "status", affiliateQueryDTO.getStatus());
qw.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime());
qw.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime());
qw.eq(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStatus()), "status", affiliateQueryDTO.getStatus())
.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime())
.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime())
.eq(!Objects.isNull(affiliateQueryDTO.getAffiliateId()), "id", affiliateQueryDTO.getAffiliateId())
.orderByDesc(affiliateQueryDTO.getOrder().equals("DESC"), "create_time");
return baseMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), qw);
}
@@ -96,6 +105,18 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
return affiliateVO;
}
public double[] getPersonalMonthlyIncome(int year){
Long accountId = UserContext.getUserHolder().getId();
List<Map<String, Object>> personalMonthlyIncome = affiliateIncomeMapper.getPersonalMonthlyIncome(accountId, year);
double[] commissions = new double[12];
personalMonthlyIncome.forEach(income -> {
int month = Integer.parseInt(income.get("yearMonth").toString());
commissions[month-1] = (double)income.get("totalCommission");
});
return commissions;
}
// 审批申请
public Boolean applicationApproval(Long id, Boolean isApproved){
Affiliate affiliate = baseMapper.selectById(id);
@@ -107,7 +128,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
affiliate.setApproved(true);
affiliate.setLink(CommonConstant.AFFILIATE_LINK + affiliate.getId());
} else {
affiliate.setStatus("Inactive");
affiliate.setStatus("Refused");
affiliate.setApproved(false);
}
affiliate.setUpdateTime(LocalDateTime.now());
@@ -142,6 +163,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
paymentInfos.forEach(paymentInfo -> {
// 2、根据order_no查付款用户id
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(paymentInfo.getOrderNo());
if (Objects.isNull(orderInfo)){
return;
}
Long accountId = orderInfo.getAccountId();
// 3、查该用户之前是否有初次订阅的订单
QueryWrapper<OrderInfo> qwOrderInfo = new QueryWrapper<>();
@@ -155,6 +179,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
// 3、若有, 直接更新affiliate的所得
Affiliate affiliate = baseMapper.selectById(account.getInvitationCode());
Float payerTotal = paymentInfo.getPayerTotal();
if (payerTotal > 0){
// 分配新用户首次订阅所付费用的25%作为佣金
BigDecimal commission = BigDecimal.valueOf(payerTotal).multiply(new BigDecimal("0.25"));
@@ -168,6 +193,17 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
baseMapper.updateById(affiliate);
orderInfo.setIsCommissionCalculated((byte)1);
// 4、添加到t_affiliate_income
AffiliateIncome affiliateIncome = new AffiliateIncome();
affiliateIncome.setAffiliateId(affiliate.getId());
affiliateIncome.setAffiliateAccountId(affiliate.getAccountId());
affiliateIncome.setInviteeAccountId(accountId);
affiliateIncome.setAmount(payerTotal);
affiliateIncome.setPaymentTime(paymentInfo.getCreateTime());
affiliateIncome.setCommission(commission.floatValue());
affiliateIncome.setCreateTime(LocalDateTime.now());
affiliateIncomeMapper.insert(affiliateIncome);
}
}
orderInfo.setIsFirstSubscription((byte)1);
@@ -190,51 +226,69 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
// 查看每个affiliate带来收入的详情
@Override
public List<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime) {
List<AffiliateInvitationDetailsVO> resp = new ArrayList<>() ;
// 1、从account表中找到所有关联了指定affiliateId的accountId
QueryWrapper<Account> qw = new QueryWrapper<>();
qw.eq("invitation_code", affiliateId);
List<Account> accountList = accountService.getBaseMapper().selectList(qw);
if (accountList.isEmpty()){
return null;
} else {
accountList.forEach(account -> {
// 2、分别找到各个accountId产生的第一笔订阅
Long accountId = account.getId();
QueryWrapper<SubscriptionInfo> subscriptionInfoQueryWrapper = new QueryWrapper<>();
subscriptionInfoQueryWrapper.eq("account_id", accountId)
.and(s -> s.eq("status", "active").or().eq("status", "canceled"))
.gt(!StringUtils.isNullOrEmpty(startTime) ,"create_time", startTime)
.lt(!StringUtils.isNullOrEmpty(endTime) ,"create_time", endTime).last("limit 1");
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(subscriptionInfoQueryWrapper);
// 2、分别第一笔订阅的付款信息
if (!Objects.isNull(subscriptionInfo)){
PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOrderNo(subscriptionInfo.getOrderNo(), "ASC").get(0);
AffiliateInvitationDetailsVO affiliateInvitationDetailsVO = new AffiliateInvitationDetailsVO();
affiliateInvitationDetailsVO.setAccountId(accountId);
affiliateInvitationDetailsVO.setUsername(account.getUserName());
affiliateInvitationDetailsVO.setFirstSubscriptionPaymentAmount(paymentInfo.getPayerTotal());
affiliateInvitationDetailsVO.setCommission(BigDecimal.valueOf(paymentInfo.getPayerTotal()).multiply(new BigDecimal("0.25")).floatValue());
affiliateInvitationDetailsVO.setTime(subscriptionInfo.getCreateTime());
resp.add(affiliateInvitationDetailsVO);
}
});
public IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO) {
if (Objects.isNull(affiliateQueryDTO.getAffiliateId())){
throw new BusinessException("Please specify the affiliate ID.", ResultEnum.PROMPT.getCode());
}
return resp;
QueryWrapper<AffiliateIncome> affiliateIncomeQueryWrapper = new QueryWrapper<>();
affiliateIncomeQueryWrapper
.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime())
.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime())
.eq(!Objects.isNull(affiliateQueryDTO.getAffiliateId()), "affiliate_id", affiliateQueryDTO.getAffiliateId())
.orderByDesc(affiliateQueryDTO.getOrder().equals("DESC"), "create_time");
IPage<AffiliateIncome> affiliateIncomePage = affiliateIncomeMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), affiliateIncomeQueryWrapper);
return affiliateIncomePage.convert((Function<AffiliateIncome, AffiliateInvitationDetailsVO>) affiliateIncome -> {
AffiliateInvitationDetailsVO affiliateInvitationDetailsVO = CopyUtil.copyObject(affiliateIncome, AffiliateInvitationDetailsVO.class);
affiliateInvitationDetailsVO.setAccountId(affiliateIncome.getInviteeAccountId());
affiliateInvitationDetailsVO.setUsername(accountService.getBaseMapper().selectById(affiliateIncome.getInviteeAccountId()).getUserName());
affiliateInvitationDetailsVO.setFirstSubscriptionPaymentAmount(affiliateIncome.getAmount());
affiliateInvitationDetailsVO.setCommission(affiliateIncome.getCommission());
affiliateInvitationDetailsVO.setTime(affiliateIncome.getPaymentTime());
return affiliateInvitationDetailsVO;
});
}
// todo 每个月给kim发一封邮件统计本月的affiliate等的收入
public void commissionCalculation(){
// 1、总收入(近一个月通过affiliate产生的收入)
public void commissionCalculation(Integer year, Integer month) {
if (Objects.isNull(year)) {
year = LocalDateTime.now().getYear();
}
if (Objects.isNull(month)) {
month = LocalDateTime.now().getMonthValue();
}
// 2、未支付的金额 affiliate表中unpaid的总和
List<Map<String, Object>> monthlyAffiliateIncome = affiliateIncomeMapper.getMonthlyAffiliateIncome(year, month);
// 1、总收入(近一个月通过affiliate产生的收入),未支付的金额 affiliate表中unpaid的总和
Double totalAmount = 0.0;
Double totalCommission = 0.0;
if (!monthlyAffiliateIncome.isEmpty()){
Map<String, Object> monthlyIncome = monthlyAffiliateIncome.get(0);
totalAmount = (Double) monthlyIncome.get("totalAmount");
totalCommission = (Double) monthlyIncome.get("totalCommission");
}
// 3、邀请的新人 查询account表中本月新增并有invitation_id的数量
// 2、本月新注册的Affiliate
Map<String, Long> monthlyApprovedAffiliate = baseMapper.getMonthlyApprovedAffiliate(year, month);
Long count = monthlyApprovedAffiliate.get("count");
AffiliateEmailParamsDTO affiliateEmailParamsDTO = new AffiliateEmailParamsDTO();
affiliateEmailParamsDTO.setTotalProgramRevenue(totalAmount.toString());
affiliateEmailParamsDTO.setNewApprovedAffiliates(count.toString());
affiliateEmailParamsDTO.setUnpaidEarnings(totalCommission.toString());
affiliateEmailParamsDTO.setPaidEarnings("0");
String receiverEmail = "xupei3360@163.com";
// String receiverEmail = "kimwong@code-create.com.hk";
// 邮件通知
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
}
@Override
public Affiliate getByAccountId(Long accountId) {
QueryWrapper<Affiliate> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("account_id", accountId).orderByDesc("id").last("limit 1");
return baseMapper.selectOne(queryWrapper);
}

View File

@@ -1004,8 +1004,8 @@ public class StripeServiceImpl implements StripeService {
try {
OrderInfo orderInfo = orderInfoService.createOrderByProductId(1, PayTypeEnum.STRIPE.getType(), ProductEnum.DailySubscription);
String customerId = getCustomer(name, email);
/* String paymentMethodCode = "pm_card_mastercard";
// String customerId = getCustomer(name, email);
String paymentMethodCode = "pm_card_mastercard";
PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodCode);
String customerId = getCustomer(name, email);
@@ -1014,14 +1014,14 @@ public class StripeServiceImpl implements StripeService {
PaymentMethodAttachParams attachParams = PaymentMethodAttachParams.builder()
.setCustomer(customerId)
.build();
paymentMethod.attach(attachParams);*/
paymentMethod.attach(attachParams);
// 设置默认付款方式
Customer updatedCustomer = Customer.retrieve(customerId);
CustomerUpdateParams params = CustomerUpdateParams.builder()
.setInvoiceSettings(
CustomerUpdateParams.InvoiceSettings.builder()
// .setDefaultPaymentMethod(paymentMethod.getId())
.setDefaultPaymentMethod(paymentMethod.getId())
.build()
)
.build();
@@ -1081,19 +1081,54 @@ public class StripeServiceImpl implements StripeService {
}
}
public String getCustomerPaymentMethod(String name, String email){
public List<Map<String,String>> getCustomerPaymentMethod(String name, String email){
Stripe.apiKey = privateKey;
try {
String customerId = getCustomer(name, email);
Customer customer = Customer.retrieve(customerId);
PaymentMethodCollection paymentMethodCollection = customer.listPaymentMethods();
List<PaymentMethod> data = paymentMethodCollection.getData();
ArrayList<Map<String,String>> resp = new ArrayList<>();
data.forEach(paymentMethod -> {
Map<String,String> map = new HashMap<>();
if (paymentMethod.getType().equals("card")){
map.put(paymentMethod.getId(),paymentMethod.getCard().getLast4());
}else {
map.put(paymentMethod.getId(),null);
}
resp.add(map);
});
// todo 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款?
return resp;
// 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款?
// 如果是的,则需要删除能成功的付款方式,保留唯一失败的付款方式进行续订付款失败测试
} catch (StripeException e) {
throw new RuntimeException(e);
}
}
public String detachCustomerAllPaymentMethod(String name, String email){
Stripe.apiKey = privateKey;
// 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款?
// 如果是的,则需要删除能成功的付款方式,保留唯一失败的付款方式进行续订付款失败测试
try {
String customerId = getCustomer(name, email);
Customer customer = Customer.retrieve(customerId);
PaymentMethodCollection paymentMethodCollection = customer.listPaymentMethods();
List<PaymentMethod> data = paymentMethodCollection.getData();
data.forEach(paymentMethod -> {
try {
PaymentMethod retrieve = PaymentMethod.retrieve(paymentMethod.getId());
PaymentMethodDetachParams params = PaymentMethodDetachParams.builder().build();
retrieve.detach(params);
} catch (StripeException e) {
throw new RuntimeException(e);
}
});
} catch (StripeException e) {
throw new RuntimeException(e);
}
return null;
}
@@ -1102,8 +1137,10 @@ public class StripeServiceImpl implements StripeService {
qw.eq("subscription_id", subscriptionId);
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
subscriptionInfo.setCancelReason(reason);
subscriptionInfoMapper.updateById(subscriptionInfo);
if (!Objects.isNull(subscriptionInfo)) {
subscriptionInfo.setCancelReason(reason);
subscriptionInfoMapper.updateById(subscriptionInfo);
}
}