山西宏图建设集团有限公司网站,wordpress怎么使用cdn加载图片,五莲建设监理有限公司网站,天津网站建设方案报价Stripe是一家美国科技公司#xff0c;成立于2010年#xff0c;由爱尔兰兄弟Patrick Collison和John Collison共同创立。该公司致力于提供高效、简洁的互联网支付收款服务#xff0c;为开发者或商家提供支付API接口或代码#xff0c;使商家的网站、移动APP支持信用卡付款。S…Stripe是一家美国科技公司成立于2010年由爱尔兰兄弟Patrick Collison和John Collison共同创立。该公司致力于提供高效、简洁的互联网支付收款服务为开发者或商家提供支付API接口或代码使商家的网站、移动APP支持信用卡付款。Stripe被誉为“移动时代的PayPal”因其简便的支付方式而受到广泛欢迎。
Stripe 总共有三种支付方式 1、Stripe Checkoutpay links 创建支付链接 2、payment intent后端预下单返回秘钥前端确定订单 3、前端创建支付token 后端创建Charge返回支付结果链接
Stripe接口调用时序图 #mermaid-svg-mFD1vJgpQFFGsQ0L {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .error-icon{fill:#552222;}#mermaid-svg-mFD1vJgpQFFGsQ0L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mFD1vJgpQFFGsQ0L .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-mFD1vJgpQFFGsQ0L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mFD1vJgpQFFGsQ0L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mFD1vJgpQFFGsQ0L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mFD1vJgpQFFGsQ0L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mFD1vJgpQFFGsQ0L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .marker.cross{stroke:#333333;}#mermaid-svg-mFD1vJgpQFFGsQ0L svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mFD1vJgpQFFGsQ0L .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-mFD1vJgpQFFGsQ0L text.actortspan{fill:black;stroke:none;}#mermaid-svg-mFD1vJgpQFFGsQ0L .actor-line{stroke:grey;}#mermaid-svg-mFD1vJgpQFFGsQ0L .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .sequenceNumber{fill:white;}#mermaid-svg-mFD1vJgpQFFGsQ0L #sequencenumber{fill:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .messageText{fill:#333;stroke:#333;}#mermaid-svg-mFD1vJgpQFFGsQ0L .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-mFD1vJgpQFFGsQ0L .labelText,#mermaid-svg-mFD1vJgpQFFGsQ0L .labelTexttspan{fill:black;stroke:none;}#mermaid-svg-mFD1vJgpQFFGsQ0L .loopText,#mermaid-svg-mFD1vJgpQFFGsQ0L .loopTexttspan{fill:black;stroke:none;}#mermaid-svg-mFD1vJgpQFFGsQ0L .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-mFD1vJgpQFFGsQ0L .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-mFD1vJgpQFFGsQ0L .noteText,#mermaid-svg-mFD1vJgpQFFGsQ0L .noteTexttspan{fill:black;stroke:none;}#mermaid-svg-mFD1vJgpQFFGsQ0L .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-mFD1vJgpQFFGsQ0L .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-mFD1vJgpQFFGsQ0L .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-mFD1vJgpQFFGsQ0L .actorPopupMenu{position:absolute;}#mermaid-svg-mFD1vJgpQFFGsQ0L .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-mFD1vJgpQFFGsQ0L .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-mFD1vJgpQFFGsQ0L .actor-man circle,#mermaid-svg-mFD1vJgpQFFGsQ0L line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-mFD1vJgpQFFGsQ0L :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 后台服务 Stripe 【初始化】客户端 StripeClient使用从Stripe平台获取的私钥 初始化成功创建 StripeClient 实例 【创建产品】 client.products().create() 创建产品成功返回产品信息 【创建产品价格】 client.prices().create()给产品创建指定币种的价格 创建产品价格成功返回价格信息 【下单】 client.checkout().sessions().create() 返回订单信息包含支付链接 session.getUrl() 和订单id 浏览器打开支付链接【完成支付】 支付完成跳转到完成页面 【支付完成回调】webhook请求 checkout.session.completed 事件返回 Session 【支付成功回调】webhook请求 charge.succeeded 事件返回 Charge 【查询订单】client.charges().retrieve(chargeId) 返回订单信息 【退款】client.refunds().create()传入 chargeId 返回退款订单信息退款ID refundId 【查询退款订单】 client.refunds().retrieve(refundId) 或 client.refunds().list() 返回退款订单信息 后台服务 Stripe 0、初始化客户端
StripeClient client StripeClient.builder().setConnectTimeout(30 * 1000).setReadTimeout(80 * 1000).setApiKey(sk_test_51PtO7DC6XhwanSnNvGezNPc4hsL2F****).build();1、产品
查询或创建新产品。
每次交易传入产品名称或描述自动查询是否已经存在如果存在则直接使用如果不存在则新建产品。
private Product getProduct(StripeOrder stripeOrder) throws StripeException {ProductSearchParams searchParams ProductSearchParams.builder().setQuery(active:true AND name: stripeOrder.getSubject() AND description: stripeOrder.getBody() ).setLimit(1L).build();StripeSearchResultProduct result client.products().search(searchParams);Product product;if (result ! null !result.getData().isEmpty()) {product result.getData().stream().findFirst().get();} else {//创建产品 https://stripe.com/docs/api/products/createProductCreateParams params ProductCreateParams.builder().setDescription(stripeOrder.getBody()).setName(stripeOrder.getSubject()).build();product client.products().create(params);}return product;}2、价格
根据产品ID创建对应币种的价格指定 lookupKey 价格币种产品ID作为价格关键字用于查询是否已经存在。如果价格存在则直接使用如果不存在则新增新的价格。
private Price getPrice(StripeOrder stripeOrder, String productId) throws StripeException {Long unitAmount Util.conversionCentAmount(stripeOrder.getPrice());String lookupKey unitAmount stripeOrder.getCurrencyCode() productId;PriceSearchParams params PriceSearchParams.builder().setQuery(active:true AND product: productId AND currency: stripeOrder.getCurrencyCode() AND lookup_key: lookupKey ).build();StripeSearchResultPrice result client.prices().search(params);Price price;if (result ! null !result.getData().isEmpty()) {price result.getData().stream().findFirst().get();} else {//创建价格 https://stripe.com/docs/api/prices/create
// PriceCreateParams.Recurring recurring PriceCreateParams.Recurring.builder()
// .setInterval(PriceCreateParams.Recurring.Interval.MONTH).build();PriceCreateParams priceCreateParams PriceCreateParams.builder().setCurrency(stripeOrder.getCurrencyCode()).setProduct(productId).setLookupKey(lookupKey).setUnitAmount(unitAmount)
// .setRecurring(recurring).build();price client.prices().create(priceCreateParams);}return price;
}3、创建支付
根据上次返回的价格信息创建新的支付对象这里指定银行卡支付也可以指定别的支付方式Stripe支持几十种支付方式可以根据不同国家选择具体可以在这里查看
下面通过 client.checkout().sessions().create() 创建支付取得支付链接在浏览器直接打开即可支付。
public MapString, Object orderInfo(PayOrder order) {StripeOrder stripeOrder (StripeOrder) order;try {Product product getProduct(stripeOrder);Price price getPrice(stripeOrder, product.getId());//创建支付信息 得到urlSessionCreateParams sessionCreateParams SessionCreateParams.builder().setMode(SessionCreateParams.Mode.PAYMENT).addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD)
// .addPaymentMethodType(SessionCreateParams.PaymentMethodType.ALIPAY).setSuccessUrl(payConfigStorage.getReturnUrl()).setCancelUrl(payConfigStorage.getCancelUrl()).setCustomer(stripeOrder.getCustomer()).setClientReferenceId(stripeOrder.getClientReferenceId()).setCustomerEmail(stripeOrder.getCustomerEmail()).addLineItem(SessionCreateParams.LineItem.builder().setQuantity(1L).setPrice(price.getId()).build()).putMetadata(outTradeNo, stripeOrder.getOutTradeNo()).build();Session session client.checkout().sessions().create(sessionCreateParams);LOG.info(session:{}, JSON.toJSONString(session));return preOrderHandler(Collections.singletonMap(paymentLink, session.getUrl()), order);} catch (StripeException e) {throw new RuntimeException(e);}
}4、打开支付链接完成支付
输入Stripe平台提供的测试卡信息完成支付
testexample.com
4242 4242 4242 4242
12/34
567
Zhang San
United States
123455、支付订单查询
传入回调信息中得到的chargeId查询订单状态。在返回的json数据了包含支付平台receiptUrl
public MapString, Object query(AssistOrder assistOrder) {try {Charge charge client.charges().retrieve(assistOrder.getTradeNo());// 使用Hutool的BeanUtil将User对象转换为Mapreturn BeanUtil.beanToMap(charge);} catch (Exception e) {throw new RuntimeException(e);}
}支付凭证 6、退款
传入回调信息中得到的chargeId提交退款请求返回退款订单信息包含退款订单Id可用于查询退款订单
public RefundResult refund(RefundOrder refundOrder) {RefundCreateParams params RefundCreateParams.builder().setCharge(refundOrder.getTradeNo()).build();try {Refund refund client.refunds().create(params);LOG.info(refund:{}, JSON.toJSONString(refund));StripeRefundResult refundResult new StripeRefundResult(refund, refundOrder.getTradeNo());refundOrder.setRefundNo(refundResult.getRefundNo());return refundResult;} catch (StripeException e) {throw new RuntimeException(e);}
}7、退款查询
传入回调信息中得到的chargeId查询退款订单也可以通过退款订单Id查询。
public MapString, Object refundquery(RefundOrder refundOrder) {RefundListParams params RefundListParams.builder().setCharge(refundOrder.getTradeNo()).build();try {StripeCollectionRefund result client.refunds().list(params);if (!result.getData().isEmpty()) {Refund refund result.getData().stream().findFirst().get();// 使用Hutool的BeanUtil将User对象转换为Mapreturn BeanUtil.beanToMap(refund);}} catch (StripeException e) {throw new RuntimeException(e);}return null;
}8、回调通知
登录Stripe平台在https://dashboard.stripe.com/workbench/webhooks中配置Webhook菜单地址“开发人员-Webhook”。
Webhook回调代码示例
public class StripePayMessageHandler implements PayMessageHandlerPayMessage, StripePayService {private final Logger LOG LoggerFactory.getLogger(getClass());private final String endpointSecret whsec_HlzC2omyh4V4X3BCgMx5PScTCmwZpvAC;//webhook秘钥签名Overridepublic PayOutMessage handle(PayMessage payMessage, MapString, Object context, StripePayService payService) throws PayErrorException {MapString, Object message payMessage.getPayMessage();NoticeParams noticeParams (NoticeParams) context.get(noticeParams);try {String sigHeader noticeParams.getHeader(Stripe-Signature);Event event Webhook.constructEvent(noticeParams.getBodyStr(), sigHeader, endpointSecret);//验签并获取事件StripeObject eventObj event.getDataObjectDeserializer().getObject().get();LOG.info(EventType:{}, Event:{}, event.getType(), JSON.toJSONString(eventObj));PaymentIntent intent;Charge charge;String outTradeNo;String chargeId;String receiptUrl;switch (event.getType()) {case charge.succeeded://支付成功//TODO 支付成功处理业务逻辑charge (Charge) eventObj;// 取得 chargeId 在退款时使用chargeId charge.getId();receiptUrl charge.getReceiptUrl();message.put(trade_no, chargeId);LOG.info(支付成功 Charge, chargeId:{}, receiptUrl:{}, chargeId, receiptUrl);break;case checkout.session.completed:// 通过支付链接 支付完成//TODO 支付完成处理业务逻辑Session session (Session) eventObj;outTradeNo session.getMetadata().get(outTradeNo);//自定义订单号LOG.info(支付完成 Session 订单号为{}, outTradeNo);message.put(out_trade_no, outTradeNo);break;case charge.refunded://退款成功charge (Charge) eventObj;if (charge.getStatus().equals(succeeded)) {//TODO 退款成功处理业务逻辑chargeId charge.getId();receiptUrl charge.getReceiptUrl();message.put(trade_no, chargeId);LOG.info(退款成功, chargeId:{}, receiptUrl:{}, chargeId, receiptUrl);}break;case checkout.session.expired://过期break;case payment_intent.created://创建订单 这里事件就是图二选着的事件break;case payment_intent.canceled://取消订单break;case payment_intent.succeeded://支付成功intent (PaymentIntent) eventObj;MapString, String metaData intent.getMetadata();//自定义传入的参数outTradeNo metaData.get(outTradeNo);//自定义订单号message.put(out_trade_no, outTradeNo);LOG.info(支付成功 payment_intent 订单号为{}, outTradeNo);//*********** 根据订单号从数据库中找到订单并将状态置为成功 *********//*break;case payment_intent.payment_failed://支付失败intent (PaymentIntent) eventObj;LOG.info(Failed: intent.getId());break;default:break;}} catch (Exception e) {LOG.error(stripe异步通知webhook事件, e);}// TODO 支付确认逻辑处理return payService.successPayOutMessage(payMessage);}
}参考
https://docs.stripe.com/apihttps://docs.stripe.com/jshttps://docs.stripe.com/webhookshttps://docs.stripe.com/search#query-fields-for-products 文章转载自: http://www.morning.mstrb.cn.gov.cn.mstrb.cn http://www.morning.kzcfp.cn.gov.cn.kzcfp.cn http://www.morning.bpmdz.cn.gov.cn.bpmdz.cn http://www.morning.pbpcj.cn.gov.cn.pbpcj.cn http://www.morning.fwkjp.cn.gov.cn.fwkjp.cn http://www.morning.leeong.com.gov.cn.leeong.com http://www.morning.kjcfz.cn.gov.cn.kjcfz.cn http://www.morning.dbddm.cn.gov.cn.dbddm.cn http://www.morning.zhishizf.cn.gov.cn.zhishizf.cn http://www.morning.gydsg.cn.gov.cn.gydsg.cn http://www.morning.ppgdp.cn.gov.cn.ppgdp.cn http://www.morning.hxgly.cn.gov.cn.hxgly.cn http://www.morning.npqps.cn.gov.cn.npqps.cn http://www.morning.jbztm.cn.gov.cn.jbztm.cn http://www.morning.qgmbx.cn.gov.cn.qgmbx.cn http://www.morning.yghlr.cn.gov.cn.yghlr.cn http://www.morning.lhrwy.cn.gov.cn.lhrwy.cn http://www.morning.hqjtp.cn.gov.cn.hqjtp.cn http://www.morning.kyfrl.cn.gov.cn.kyfrl.cn http://www.morning.brbnc.cn.gov.cn.brbnc.cn http://www.morning.djxnn.cn.gov.cn.djxnn.cn http://www.morning.kqxwm.cn.gov.cn.kqxwm.cn http://www.morning.dphmj.cn.gov.cn.dphmj.cn http://www.morning.dywgl.cn.gov.cn.dywgl.cn http://www.morning.kybyf.cn.gov.cn.kybyf.cn http://www.morning.gqjzp.cn.gov.cn.gqjzp.cn http://www.morning.mdwb.cn.gov.cn.mdwb.cn http://www.morning.hlfnh.cn.gov.cn.hlfnh.cn http://www.morning.ccsdx.cn.gov.cn.ccsdx.cn http://www.morning.ymjgx.cn.gov.cn.ymjgx.cn http://www.morning.wptdg.cn.gov.cn.wptdg.cn http://www.morning.qwdlj.cn.gov.cn.qwdlj.cn http://www.morning.jljwk.cn.gov.cn.jljwk.cn http://www.morning.jksgy.cn.gov.cn.jksgy.cn http://www.morning.nrqnj.cn.gov.cn.nrqnj.cn http://www.morning.wjqyt.cn.gov.cn.wjqyt.cn http://www.morning.lbpfl.cn.gov.cn.lbpfl.cn http://www.morning.ktmbp.cn.gov.cn.ktmbp.cn http://www.morning.mmjyk.cn.gov.cn.mmjyk.cn http://www.morning.rxlk.cn.gov.cn.rxlk.cn http://www.morning.fbpyd.cn.gov.cn.fbpyd.cn http://www.morning.fsrtm.cn.gov.cn.fsrtm.cn http://www.morning.zkzjm.cn.gov.cn.zkzjm.cn http://www.morning.pxbky.cn.gov.cn.pxbky.cn http://www.morning.hksxq.cn.gov.cn.hksxq.cn http://www.morning.fxzlg.cn.gov.cn.fxzlg.cn http://www.morning.cczrw.cn.gov.cn.cczrw.cn http://www.morning.tmbfz.cn.gov.cn.tmbfz.cn http://www.morning.ybshj.cn.gov.cn.ybshj.cn http://www.morning.yprnp.cn.gov.cn.yprnp.cn http://www.morning.jjnry.cn.gov.cn.jjnry.cn http://www.morning.htbgz.cn.gov.cn.htbgz.cn http://www.morning.qzpkr.cn.gov.cn.qzpkr.cn http://www.morning.rqgjr.cn.gov.cn.rqgjr.cn http://www.morning.jgcyn.cn.gov.cn.jgcyn.cn http://www.morning.txhls.cn.gov.cn.txhls.cn http://www.morning.nqpxs.cn.gov.cn.nqpxs.cn http://www.morning.mtdfn.cn.gov.cn.mtdfn.cn http://www.morning.zylzk.cn.gov.cn.zylzk.cn http://www.morning.nydgg.cn.gov.cn.nydgg.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.wmrgp.cn.gov.cn.wmrgp.cn http://www.morning.jfqpc.cn.gov.cn.jfqpc.cn http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn http://www.morning.zbkwj.cn.gov.cn.zbkwj.cn http://www.morning.yrjkz.cn.gov.cn.yrjkz.cn http://www.morning.snbrs.cn.gov.cn.snbrs.cn http://www.morning.demoux.com.gov.cn.demoux.com http://www.morning.nzqmw.cn.gov.cn.nzqmw.cn http://www.morning.hytqt.cn.gov.cn.hytqt.cn http://www.morning.srltq.cn.gov.cn.srltq.cn http://www.morning.kpbn.cn.gov.cn.kpbn.cn http://www.morning.fpyll.cn.gov.cn.fpyll.cn http://www.morning.tnmmp.cn.gov.cn.tnmmp.cn http://www.morning.rfrx.cn.gov.cn.rfrx.cn http://www.morning.wjlnz.cn.gov.cn.wjlnz.cn http://www.morning.rshijie.com.gov.cn.rshijie.com http://www.morning.rgpbk.cn.gov.cn.rgpbk.cn http://www.morning.ngjpt.cn.gov.cn.ngjpt.cn http://www.morning.hjwxm.cn.gov.cn.hjwxm.cn