1. 首先引用maven
stripe的API版本调用版本呢需要对应,切记看stripe后台webhook对应的API版本
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>23.9.0</version>
</dependency>
2. checkout 方式,创建订单,注意订阅的商品和一次性付款的商品不同,
创建商品和价格
public class StripeUtils {
public static void createPrice(GoodsDetail goodsDetail, Goods goods) throws StripeException {
Map<String, Object> priceParams = new HashMap<>();
priceParams.put("unit_amount", goodsDetail.getUnitPrice().multiply(new BigDecimal(100)).toBigInteger().intValue());
priceParams.put("currency", "USD");
priceParams.put("product", goods.getStripeProductId());
if (goodsDetail.isSubscribe()) {
Map<String, Object> recurring = new HashMap<>();
recurring.put("interval", "month");
recurring.put("interval_count", 1);
priceParams.put("recurring", recurring);
}
Price price = Price.create(priceParams);
goodsDetail.setStripePriceId(price.getId());
}
public static void createProduct(Goods goods) throws StripeException {
Map<String, Object> params = new HashMap<>();
params.put("name", goods.getName());
params.put("description", goods.getDescription());
Product product = Product.create(params);
goods.setStripeProductId(product.getId());
}
}
创建订单,获取支付URL
AuthenticationUser user = SecurityUtils.getLoginUser();
GoodsDetail goodsDetail = goodsDetailService.getById(goodsDetailId);
Result result = tradeOrderService.checkCreateOrder(goodsDetail, orgId, user.getId());
if (! "200".equals(result.getCode())) {
return result;
}
TradeOrder order = tradeOrderService.createOder(goodsDetail, user.getId(), orgId, "stripe");
SessionCreateParams.Builder builder = SessionCreateParams.builder();
// 检查是否是订阅模式的商品
if (ServiceUtils.autoSubscribe(order.getAutoSubscribe())) {
builder.setMode(SessionCreateParams.Mode.SUBSCRIPTION);
builder.setSubscriptionData(SessionCreateParams.SubscriptionData.builder().putMetadata("order_id", order.getId().toString()).build());
} else {
builder.setMode(SessionCreateParams.Mode.PAYMENT);
builder.setPaymentIntentData(SessionCreateParams.PaymentIntentData.builder().putMetadata("order_id", order.getId().toString()).build());
}
SessionCreateParams params =
builder.setSuccessUrl(successURL)
.setCancelUrl(cancelURL)
.addLineItem(
SessionCreateParams.LineItem.builder()
.setQuantity(1L)
// Provide the exact Price ID (for example, pr_1234) of the product you want to sell
// 传入价格ID
.setPrice(order.getStripePriceId())
.build())
.build();
Session session = Session.create(params);
order.setPaymentUrl(session.getUrl());
tradeOrderService.updateById(order);
return Result.success(SuccessMessageEnum.OPERATION_SUCCESS, order);
3. 在sripe管理后台配置webhook端点,监听对应事件后,对应回调代码
try {
String sigHeader = request.getHeader("Stripe-Signature");
Event event = null;
try {
event = Webhook.constructEvent(
payload, sigHeader, endpointSecret
);
} catch (SignatureVerificationException e) {
// Invalid signature
log.error("error", e);
response.setStatus(400);
return "";
}
// Deserialize the nested object inside the event
EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
StripeObject stripeObject = null;
if (dataObjectDeserializer.getObject().isPresent()) {
stripeObject = dataObjectDeserializer.getObject().get();
} else {
// Deserialization failed, probably due to an API version mismatch.
// Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
// instructions on how to handle this case, or return an error here.
response.setStatus(400);
}
// Handle the event
switch (event.getType()) {
case "payment_intent.canceled": {
// Then define and call a function to handle the event payment_intent.canceled
PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
log.info("payment_intent.canceled : order_id : {}", paymentIntent.getMetadata().get("order_id"));
break;
}
// 一次性付款下的回调处理
case "payment_intent.succeeded": {
// Then define and call a function to handle the event payment_intent.succeeded
PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
log.info("payment_intent.succeeded : trade_no: {} , order_id : {}", paymentIntent.getId(), paymentIntent.getMetadata().get("order_id"));
String orderId = paymentIntent.getMetadata().get("order_id");
if (StringUtils.hasText(orderId)) {
TradeOrder tradeOrder = tradeOrderService.getById(orderId);
if (! ServiceUtils.isOrderSuccess(tradeOrder.getStatus())) {
tradeOrder.setTradeNo(paymentIntent.getId());
tradeOrderService.successOrder(tradeOrder);
}
}
break;
}
// 订阅模式下回调处理
case "invoice.payment_succeeded": {
// Then define and call a function to handle the event payment_intent.succeeded
Invoice invoice = (Invoice) stripeObject;
log.info("invoice.payment_succeeded : sub_id : {}, order_id: {}", invoice.getSubscription(), invoice.getSubscriptionDetails().getMetadata().get("order_id"));
String orderId = invoice.getSubscriptionDetails().getMetadata().get("order_id");
TradeOrder tradeOrder = tradeOrderService.getById(orderId);
if (! ServiceUtils.isOrderSuccess(tradeOrder.getStatus())) {
tradeOrder.setTradeNo(invoice.getSubscription()); // 自动订阅存储的是订阅ID
tradeOrderService.successOrder(tradeOrder);
}
break;
}
// 取消订阅回调处理
case "customer.subscription.deleted": {
// Then define and call a function to handle the event payment_intent.succeeded
Subscription subscription = (Subscription) stripeObject;
log.info("customer.subscription.deleted : sub_id : {}", subscription.getItems().getData().get(0).getSubscription());
String subId = subscription.getItems().getData().get(0).getSubscription();
Subscribe subscribe = subscribeService.getOne(Wrappers.<Subscribe>lambdaQuery().eq(Subscribe::getSubscribeId, subId));
if (subscribe != null) {
subscribe.setAutoSubscribe(0);
subscribeService.saveOrUpdate(subscribe);
}
break;
}
// ... handle other event types
default:
log.info("Unhandled event type: " + event.getType());
}
response.setStatus(200);
return "";
} catch (Exception e) {
log.error("error", e);
response.setStatus(400);
return "";
}