首先在STRIPE官网注册账号之后进入首页,点击API密钥,查看账号对应的密钥以及测试密钥,测试密钥以sk_test,正式sk_live开头
sk_test开头的密钥用于服务端
pk_test开头用于客户端,如:web,Android,iOS
然后进入下面的WEBHOOK页面,选择添加端点,如果是要调自己本地代码测试的话,其中端点url需要给自己电脑配置一个内网穿透(你用自己本地localhost作为回调的url肯定是不支持的),也可以在webhook页面中选择“在本地环境中测试”,通过官方的CLI进行本地测试。
创建完webhook端点后可以看到自己webhook首页有一个 密钥签名,以whsec开头
此时最重要的两个密钥就已经获得了,一个API.KEY(调用STRIPE支付验证),一个webhook密钥(用于WEBHOOK回调验证)在后面代码中这两个密钥都需要用上。
在刚刚创建WEBHOOK端点中可以看到有一个选择事件,其中我们选择监听payment_intent支付成功、失败、取消、创建四种状态,payment_intent是调用STRIPE支付过程中STRIPE自动创建的(也可以在代码中手动创建去扩展功能),通过这个payment_intent(支付意向)可以监听到你往STRIPE发送的支付请求的状态,捕获到状态之后再通过webhook回调到你自己的代码中。也就是监听到状态之后回调到你端点URL中。
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>21.8.0</version>
</dependency>
根据整个支付流程我们可以把后端简单的划分为一个调用STRIPE的接口,一个用户接收STRIPE WEBHOOK回调的接口。也就是说调用STRIPE方和接收STRIPE回调方需要通过两个不同的密钥去与STRIPE进行验证
Stripe收款有三种方式:
Stripe Checkout 是一个预构建的页面,可将您的客户重定向到这里,方便地完成购买和订阅。它提供了很多功能,例如 Apple Pay、Google Pay、国际化及表单验证。
Charges 和 Payment Intents API 可供您创建自定义的付款流程和使用体验。
Payment Intents API 是所有 Stripe 产品和支付方式的统一 API。虽然我们并未弃用 Charges,但新功能只可通过 Payment Intents API 来提供。
CHARGES API | PAYMENT INTENTS API |
常由主要客户群在美国/加拿大而想用一种可接受银行卡付款的简单方式的商家使用。 | 接受多种支付方式及银行卡需要验证的公司要求使用(例如,由于欧洲的强客户验证)。 |
适用于 Web、iOS 和 Android。 | 适用于 Web、iOS 和 Android。也可用于通过 Terminal 进行店内收款。 |
Sources API 支持银行卡及所有支付方式。 | 支持银行卡,需要 3DS 验证的银行卡、iDEAL、SEPA 及很多其他支付方式。 |
不是 SCA ready 的 |
Stripe.apiKey = apiKey;
Map<String, Object> productParams = new HashMap();
productParams.put("name", "test");
//产品图片
List<String> images = new ArrayList();
images.add("imges");
productParams.put("images", images);
Product product = Product.create(productParams);
Stripe.apiKey = apiKey;
//设置产品价格,数量
Map<String, Object> priceParams = new HashMap();
priceParams.put("unit_amount", 100);//商品价格(分为单位)
priceParams.put("currency", "USD");
priceParams.put("product", product.getId());//创建产品时的ID
Price price = Price.create(priceParams);
Stripe.apiKey = apiKey;
//设置购买产品,购买数量
List<Map<String, Object>> lineItems = new ArrayList<>();
Map<String, Object> lineItem = new HashMap();
lineItem.put("price", price.getId());//价格ID
lineItem.put("quantity", 2);
lineItems.add(lineItem);
//自定义参数
Map<String, Object> metadata = new HashMap<>();
//TODO 必须使用https 返回的回调地址
String uuid = UUID.randomUUID().toString();
metadata.put("order_id", uuid);//业务系统唯一标识 即订单唯一编号
metadata.put("source", 1);//来源:0,询盘,2.订单
Map<String, Object> params = new HashMap();
params.put("currency", "USD");//设置币种
params.put("success_url", "");//成功返回链接
params.put("cancel_url", “”);//失败返回链接
params.put("line_items", lineItems);//产品集合
params.put("metadata", metadata);//自定义参数
params.put("mode", SessionCreateParams.Mode.PAYMENT);//支付模式
Session session = Session.create(params);
6.自定义支付(Payment Intents API支付方式)
自定义支付:
1. 多方支付(一部分转入平台,一部分转入商家)
2. 平台收取(全部平台收取)
paymentIntent.getClientSecret()获取客户端密钥,客户端调用stripe支付传这个参数
Stripe.apiKey = apiKey;
//支付到自己平台
PaymentIntentCreateParams params =
PaymentIntentCreateParams
.builder()
.setAmount(1099L)//支付金额
.setCurrency("USD")//货币
.addPaymentMethodType("card")//自定义设置支持什么支付方式
.setAutomaticPaymentMethods(
PaymentIntentCreateParams.AutomaticPaymentMethods.builder().setEnabled(true).build()
) .build();//这个属性会从管理平台获取配置的支付方式
PaymentIntent paymentIntent = PaymentIntent.create(params);
//多方支付
//单位:分,收取经销商成本价,手续费将从经销商扣除
params.put("application_fee_amount", applicationFeeAmount.longValue());//设置子账号
RequestOptions requestOptions=RequestOptions.builder().setStripeAccount(accountId).build();
paymentIntent = PaymentIntent.create(params, requestOptions);
7. 创建经销商用户(多方支付)
创建用户分为三种
1.Standard(由stripe平台生成链接,收取验证商户信息, demo使用的是这种方式)
2.Express(商户信息一部分平台收取,一部分stripe收取)
3.Custom(完全平台收取验证商户信息)
Stripe.apiKey = apiKey;
//metadata 是自定义参数
Map<String, String> metadata = new HashMap<>();
metadata.put("retailerId", retailerId + "");
metadata.put("proId", proId + "");
AccountCreateParams params =
AccountCreateParams.builder()
.setMetadata(metadata)
//type:创建用户类型一共有三种:自定义用户,自定义+stripe平台注册,完全stripe平台注册
.setType(AccountCreateParams.Type.STANDARD).build();
Account account = Account.create(params);
Stripe.apiKey = apiKey;
//生成注册链接
AccountLinkCreateParams accLinkParam =
AccountLinkCreateParams
.builder()
.setAccount(accountId)//初始化用户stripe用户ID
.setRefreshUrl(refreshUrl)//用户入职刷新页面或者链接过期跳转的链接
.setReturnUrl(returnUrl)//入职成功后返回的页面
.setType(AccountLinkCreateParams.Type.ACCOUNT_ONBOARDING)//创建链接类型
.build();
AccountLink accountLink = AccountLink.create(accLinkParam);
accountLink.getUrl()//这个就是生成的入职链接
一.下载
从 https://github.com/stripe/stripe-cli/releases/latest 下载最新的 windows tar.gz 文件
二.登录
打开命令行,进入CLI目录,在命令行中输入stripe login登录stripe账户
stripe login --api-key {{TEST_API_KEY}} 也可以通过apikey登录
三.输入本地访问webhook链接
stripe listen --forward-to http://localhost:4242/webhook然后输入webhook回调链接
一种是订单支付成功,一种是用户入职成功
String payload = null;
String sigHeader= null;
String endpointSecret = "whsec_xxxgx92OjXdBf1lc2c";//webhook秘钥签名
try {
sigHeader = request.getHeader("Stripe-Signature");
payload = RequestParsingUtil.getBody(request);
} catch (Exception e) {
log.info("stripe 支付回调参数解析异常:errorMsg {}", e.getMessage());
log.info("request sigHeader = {}", sigHeader);
log.info("request body = {}", payload);
e.printStackTrace();
response.setStatus(400);
}
Event event = null;
try {
event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
} catch (SignatureVerificationException e) {
log.info("stripe 验签,获取事件异常, errorMsg=" + e.getMessage());
log.info("request sigHeader = {}", sigHeader);
log.info("request body = {}", payload);
e.printStackTrace();
response.setStatus(400);
}
//获取自定义参数
// Deserialize the nested object inside the event
EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
StripeObject stripeObject = null;
if (dataObjectDeserializer.getObject().isPresent()) {
stripeObject = dataObjectDeserializer.getObject().get();
} else {
log.info("stripe 验签失败!");
log.info("request sigHeader = {}", sigHeader);
log.info("request body = {}", payload);
response.setStatus(400);
}
switch (event.getType()) {
case "account.updated"://用户状态变化
String connectedAccountId = event.getAccount();
Account account = Account.retrieve(connectedAccountId);//获取stripe用户信息
case "payment_intent.created"://创建订单,不做处理
break;
case "payment_intent.canceled"://取消订单
break;
case "payment_intent.succeeded"://支付成功
PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
Map<String,String> metaData = paymentIntent.getMetadata();//自定义传入参数
String order_id = metaData.get("order_id");//自定义订单号
paymentIntent.getId();
//根据订单号从数据库中找到订单,并将状态置为成功
break;
case "payment_intent.payment_failed"://支付失败
//System.out.println("Failed: " + intent.getId());
break;
default:
break;
}
response.setStatus(200);