最近在接海外支付的API,然后打算记录下来我接触的过程
API地址:Stripe API reference – The review object – Java
线上支付方式
我这次介绍的是CheckOut方式创建链接支付
package com.example.demo.stripe;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Charge;
import com.stripe.model.PaymentIntent;
import com.stripe.model.Price;
import com.stripe.model.Product;
import com.stripe.model.checkout.Session;
import com.stripe.param.checkout.SessionCreateParams;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@Component
public class StripeCheckOutLinkConfig {
// payment_status paid 付费 unpaid 未支付
static {
// 管理平台里面的密钥 详情请看 demo-image/1.jpg ,图片地址链接: https://dashboard.stripe.com/test/apikeys
Stripe.apiKey = "sk_test_51NpiHFEaneEdIgupMumbxloEpbxvkeJ0LvxYh9v6yTXgaYTKAOWbgFF0s8jSJaYzx3OWVlG61KzY4Mm83VvuUHiW00tZotm2Da";
// staticFiles.externalLocation(Paths.get("public").toAbsolutePath().toString());
}
public static void main(String[] args) throws StripeException {
String uuid = UUID.randomUUID().toString();
String sessionId = new StripeCheckOutLinkConfig().getLink(uuid);
// cs_test_a1DaFDAifdbP9R0Z1hO742CouNx4LzE4lbOR8jinIQwqu5KVudxKzHn3ZQ
// cs_test_a1yYFEqeIQgusYptPZ5Cocw6ZpBPGzVF1UvPK5tSA0r0YYV2Yow52zacZf // 超时不支付
// cs_test_a1IgVjw1frUat51X3flwOWD9XAEYF84IdHHJoW8ud6rnBylxGQtgd8fnSu
// new StripeCheckOutLinkConfig().checkOutDetail("cs_test_a1qWQoX1Uh7O3EtjZ90PB0mEaBdL2yGUEGfzFIc9wx7xmrJ8DA5qOJ1wCW");
// new StripeConfig().refund("cs_test_a1IgVjw1frUat51X3flwOWD9XAEYF84IdHHJoW8ud6rnBylxGQtgd8fnSu");
// new StripeCheckOutLinkConfig().linkExpire("cs_test_a1LCWupLBmdSC8W3CJMX4vY7X9sjlu3LBlpCzajt9Bvh23mox6N5psn98B");
}
public String getLink(String orderId) throws StripeException {
Map<String, Object> productParam = new HashMap<>();
productParam.put("name", "产品名称");
Product product = Product.create(productParam);
Map<String, Object> priceParam = new HashMap<>();
int amount = 50000;
priceParam.put("unit_amount", amount);
priceParam.put("currency", "CNY");
priceParam.put("product", product.getId());
Price price = Price.create(priceParam);
BigDecimal time = new BigDecimal(24 * 30 * 60);
long expire = Instant.now().getEpochSecond() + time.longValue();
System.out.println("expire time---" + expire);
//创建支付信息 得到url 设置过期时间
SessionCreateParams params3 = SessionCreateParams.builder()
.setMode(SessionCreateParams.Mode.PAYMENT).setExpiresAt(expire)
.setSuccessUrl("http://127.0.0.1:9090/stripe/success")
// .setCancelUrl( "http://127.0.0.1:9090/stripe/cancel")
.addLineItem(
SessionCreateParams.LineItem.builder()
.setQuantity(1L)
.setPrice(price.getId())
.build())
.putMetadata("orderId", orderId).setLocale(SessionCreateParams.Locale.EN) //业务系统唯一标识 即订单唯一编号
.build();
Session session = Session.create(params3);
System.out.println(session.getId());
System.out.println(session.getUrl());
return session.getId();
}
/**
* 获取详情
* @param sessionId
* @throws StripeException
*/
public void checkOutDetail(String sessionId) throws StripeException {
Session session = Session.retrieve(sessionId);
PaymentIntent paymentIntent = PaymentIntent.retrieve(session.getPaymentIntent());
Charge charge = Charge.retrieve(paymentIntent.getLatestCharge());
System.out.println(StripeConfig.gson.toJson(charge));
// 订单信息
JSONObject jsonObject = JSON.parseObject(session.getLastResponse().body());
Map map = JSONObject.toJavaObject(jsonObject, Map.class);
System.out.println(JSONObject.toJSON(map));
}
/**
* 链接过期
* @param sessionId
* @throws StripeException
*/
public void linkExpire(String sessionId) throws StripeException {
Session session = Session.retrieve(sessionId);
session.expire();
}
/**
* 退款
* @param sessionId
* @throws StripeException
*/
public void refund(String sessionId) throws StripeException {
Session session = Session.retrieve(sessionId);
if(session.getPaymentIntent() != null) {
BigDecimal refundAmount = new BigDecimal(10000);
RefundCreateParams params = RefundCreateParams.builder().setPaymentIntent(session.getPaymentIntent()).setAmount(refundAmount.longValue()).build();
Refund refund = Refund.create(params);
// TODO 判断那个状态是 pending / succeeded / failed 的
System.out.println(refund);
}else {
System.out.println("订单未付款");
}
}
}
Stripe回调接口
package com.example.demo.stripe;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stripe.model.Event;
import com.stripe.model.PaymentIntent;
import com.stripe.net.Webhook;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@Component
public class StripeCallbackConfig {
private final static String WEB_HOOKS_SECRET_LOCAL = "whsec_e4e5ce87acdd75d5204a62f1bcea28d5688a2de966e227d6a5cdd3e08b40bd1b";
/**
* 事件触发成功的回调接口
* @param request
*/
public void callback(HttpServletRequest request){
try{
InputStream inputStream = request.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
output.write(buffer, 0, n);
}
byte[] bytes = output.toByteArray();
String payload = new String(bytes, "UTF-8");
String sigHeader = request.getHeader("Stripe-Signature");
Event event = Webhook.constructEvent(payload, sigHeader, WEB_HOOKS_SECRET_LOCAL);//验签,并获取事件
System.out.println(event.getType());
switch(event.getType()) {
case "checkout.session.completed"://支付完成
System.out.println("---------------success2222222---------------");
// System.out.println(event);
String data = event.getDataObjectDeserializer().getRawJson();
JSONObject dataObject = JSON.parseObject(data);
Object meteData = dataObject.get("metadata");
JSONObject meteDataObject = JSON.parseObject(meteData.toString());
String orderId = meteDataObject.getString("orderId");
System.out.println("订单号为:"+orderId);
Object paymentIntentId = dataObject.get("payment_intent");
PaymentIntent pay = PaymentIntent.retrieve(paymentIntentId.toString());
System.out.println("paymentIntent:"+pay);
System.out.println("根据订单号从数据库中找到订单,并将状态置为支付成功状态");
break;
case "checkout.session.async_payment_failed" :
System.out.println("---------------预付失败---------------");
break;
case "checkout.session.async_payment_succeeded" :
System.out.println("---------------预付成功---------------");
break;
case "checkout.session.expired"://过期
System.out.println("---------------链接过期---------------");
String dataExpired = event.getDataObjectDeserializer().getRawJson();
System.out.println("订单号为:"+ dataExpired);
JSONObject dataObjectExpired = JSON.parseObject(dataExpired);
Object meteDataExpired = dataObjectExpired.get("metadata");
JSONObject meteDataObjectExpired = JSON.parseObject(meteDataExpired.toString());
String orderIdExpired = meteDataObjectExpired.getString("orderId");
System.out.println("订单号为:"+orderIdExpired);
System.out.println("---------------checkout.session.expired---------------");
break;
case "payment_intent.payment_failed": // 失败,支付
break;
case "charge.refunded" : // 退款等待状态 pending
//
// System.out.println("---------------拒绝---------------");
// String data1 = event.getDataObjectDeserializer().getRawJson();
// System.out.println("拒绝数据为:"+ data1);
// JSONObject dataObject1 = JSON.parseObject(data1);
// Object paymentIntentId = dataObject1.get("payment_intent");
// PaymentIntent paymentIntent = PaymentIntent.retrieve(paymentIntentId.toString());
// System.out.println("拒绝数据---paymentIntent为:"+ paymentIntent);
// Object chargeId = dataObject1.get("id");
// Charge charge = Charge.retrieve(chargeId.toString());
// System.out.println("拒绝数据---charge为:"+ charge);
break;
case "charge.refund.updated" : // 退款成功或者失败状态 succeeded / failed
System.out.println("---------------拒绝更新状态---------------");
String data2 = event.getDataObjectDeserializer().getRawJson();
JSONObject dataObject2 = JSON.parseObject(data2);
System.out.println("拒绝更新数据为:"+ dataObject2);
Object reason = dataObject2.get("failure_reason");
System.out.println("拒绝更新数据---拒绝原因为:"+ reason);
Object payId = dataObject2.get("payment_intent");
PaymentIntent paymentIntent = PaymentIntent.retrieve(payId.toString());
System.out.println("拒绝更新数据---PaymentIntent为:"+ paymentIntent);
break;
default:
break;
}
}catch (Exception e){
System.out.println("stripe异步通知(webhook事件)"+e);
}
}
}