这段时间在作支付相关的工做,因为业务主要是面向国外的用户,于是就接触了部分国外的支付支付相关的平台。接下来的内容主要是初步看了 Stripe 平台的文档所了解到的基本内容,后面会在使用的过程当中不断地进行完善。html
Stripe - 基于API的便捷支付渠道 中对Stripe所提供的功能/产品给了较为不错的参考。前端
在我写这篇博客之时(2019-04-07),stripe已经支持32个国家的使用,而我在查找资料的时候,看到的基本都是说25个国家。支持的国家(https://stripe.com/global)java
从列表中咱们能够看到,其实中国大陆是尚未被支持的。为了可以进行收钱,咱们须要一个在Stripe支持国家列表中的国家的银行帐号。若是中国的企业单位但愿使用的话,能够经过 Stripe 的 Atlas 建立一个美国的银行帐号。更多关于 Atlas 能够看下 Atlas 的主页介绍,或者看下36氪的《为何说想把业务作到海外去的公司,都须要关注 Stripe Atlas ?》。这里就不作展开介绍了。git
有朋友使用过[PayPal]()和[Square]()。PayPal的开发难度更大,隐藏的价格远比想象中的还要高,表面上看,每笔钱进来,须要付给PayPal 2.99%的费用,但实际上确付了5%还要高。并且在使用新的PayPal帐号的时候,发现新帐号不接受信用卡支付。而Square相对于PayPal,开发难度要更简单。但在开发App端的支付时,发现Square的SDK仅仅支持较低版本的安卓系统,这就不得不放弃Square了。github
不一样的平台有不一样的优缺点,总的来讲。Stripe开发简单,支付的支付方式不少(支付宝和微信支付目前都已经支持了),适合创业团队使用。而Square对线下的支付有着很好的支持,若是有线下支付的须要的业务能够考虑使用Square。而PayPal更加适合大型企业的使用。 web
支付平台的选择不是这篇文章的重点,若是想要了解更多的对比细节,能够查看以下的参考文章。 数据库
点击这里,能够查看Stripe平台的价格。编程
参考后端
支付流程)。整个支付流程仍是比较简单的,总的来讲就是前端经过Stripe平台获取支付令牌,后端利用这个支付令牌进行请求Stripe进行实际支付。用户的信用卡敏感信息不会经过咱们的后台,Stripe会帮咱们处理复杂的PCI compliance。这里会涉及到企业的免责问题。 api
为了方便咱们进行各类测试,Stripe 为咱们的测试提供了足够的测试帐号。
后台获得支付使用的token以后,在进行收款时, 设置capture为true,Stripe则会直接进行收帐。
// Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_yoursecretkey"; // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: String token = request.getParameter("stripeToken"); Map<String, Object> params = new HashMap<>(); params.put("amount", 999); params.put("currency", "usd"); params.put("description", "Example charge"); params.put("source", token); // params.put("capture", true); Charge charge = Charge.create(params);
每一个token只能使用一次,并且会很快就会失效了。事实上,token自己是不会失效的,可是CVC信息在很短的时间内可用,在延迟以后使用令牌会致使在没有CVC信息的状况下执行收费。
Stripe支持分步骤支付,能够先受权支付,而后等待稍后进行结算。交易的资金将由发卡单位进行担保。受权的有效期为七天,若是没有及时进行收费,受权将会被取消并释放资金。利用两步支付,咱们能够在支付流程中增长一个支付审核的流程,用于防止支付欺诈。
第一步: 建立一个uncaptured的charge
// Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_yoursecretkey"; // Token is created using Checkout or Elements! // Get the payment token ID submitted by the form: String token = request.getParameter("stripeToken"); Map<String, Object> params = new HashMap<>(); params.put("amount", 999); params.put("currency", "usd"); params.put("description", "Example charge"); params.put("source", token); params.put("capture", false); Charge charge = Charge.create(params);
第二步: 进行capture
// Set your secret key: remember to change this to your live secret key in production // See your keys here: https://dashboard.stripe.com/account/apikeys Stripe.apiKey = "sk_test_yoursecretkey"; Charge charge = Charge.retrieve("ch_mh4nUTTkwbhC3i9gpcm0"); charge.capture();
Stripe 能够设置每笔帐单的邮件接受,每一个charge会对该邮箱发送email。
params.put("receipt_email", "jenny.rosen@example.com");
Stripe支持添加Metadata到本身的支付请求中,将会有助于本身管理每笔支付信息。这些信息只有本身能够看到,而客户是看不到的。若是启用的Radar,能够在Radar利用这些信息的设置Radar规则。
Map<String, String> metadata = new HashMap<>(); metadata.put("order_id", 6735); params.put("metadata", metadata);
支付过程当中,会存在支付失败的结果。交易结果中会含有失败的类型和缘由描述。建议对每种失败类型进行处理,错误列表看: https://stripe.com/docs/declines/codes。decline-codes列表对应outcome.reason
。考虑是否须要将这些错误信息转化为平台的错误信息。须要注意的是,前端在获取受权的时候会有哪些错误返回,又应该如何进行展现。并非全部的交易失败均可以肯定具体的缘由,这些失败一般会返回 code
为 generic
,这时候最好让你的客户直接联系发卡银行,咨询具体缘由。
... outcome: { network_status: "declined_by_network" reason: "expired_card" risk_level: "normal" seller_message: "The bank returned the decline code `expired_card`." type: "issuer_declined" }, ...
形成失败的缘由能够总结以下:
支付被发卡单位拒绝 (type:"issuer_declined"
)
Stripe 安全屏蔽(type: "blocked")
type: "invalid"
。这个在生产环境中应该尽可能避免, 该类型失败的支付不会显示在Dashboard中)若是Stripe屏蔽了一些你知道是合法安全的支付,你能够在Dashboard中标记该卡为安全。标记为安全不会继续尝试本次支付,可是会容许其以后的支付。
若是但愿在集成环境中对支付结果进行自动的处理,能够经过以下两种方式对charge的outcome进行处理:
1. 处理支付失败时返回的API错误。 对于被冻结的和信用卡发行方拒绝的付款,错误包括该charge的ID,而后可使用该charge的ID来retrive该charge。
try { // Use Stripe's library to make requests... } catch (CardException e) { // Since it's a decline, CardException will be caught System.out.println("Status is: " + e.getCode()); System.out.println("Message is: " + e.getMessage()); } catch (RateLimitException e) { // Too many requests made to the API too quickly } catch (InvalidRequestException e) { // Invalid parameters were supplied to Stripe's API } catch (AuthenticationException e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) } catch (APIConnectionException e) { // Network communication with Stripe failed } catch (StripeException e) { // Display a very generic error to the user, and maybe send // yourself an email } catch (Exception e) { // Something else happened, completely unrelated to Stripe }
2. 使用webhooks监听事件提示。 当支付失败时,charge.failed
事件就会被触发,返回的结果会包含Charge对象。
支付平台都应该注意到交易过程当中如何处理交易纠纷和防范交易欺诈,以避免在交易过程当中处于不利地位,设置是亏钱亏货。这部份内容会不少,你能够点击这里到平台中查看更多的信息。下面的内容为我在整理的大概内容。
当持卡人向发卡单位提出付款问题时,就会发生争议(也称为退款)。发行方产生正式争议,当即撤销支付。支付的金额,连同卡网收取的另外一笔85元争议费(适用于香港的用户),会从你的账户结余中扣除。
咱们须要作的是,如何证实以前的支付是有效的。应该经过 Stripe的Dashboard进行提交资料,由于上面会有一些指导。咱们应该在纠纷有效时间内提供证据,不然将没法提供证据. 具体时间有纠纷中提供的信息。并且咱们只能提交一次资料,若是资料没有提交完整,在尝试经过email进行提交等都是没有用的。
处理纠纷是要给Stripe交手续费的。
对方获胜: 纠纷金额退换给对方和卡网收取纠纷费用HK$85.00。
我方获胜: 卡网收取纠纷费用HK$85.00,纠纷金额退换给咱们。
纠纷建立和关闭时,Stripe都会自动发送一封邮件给你,以及触发 webhook的 charge.dispute.created
和 charge.dispute.closed
事件。
纠纷中须要提交的证据(后台开发中须要注意保留这些信息)
为了防范纠纷和欺诈,咱们须要在开发的时候留意一些必要的操做。
1. 收集尽量多的支付信息
有些信息时在前端获取token的时候收集,有些是在后台进行charge的时候收集。(这里须要确认那些信息须要提供给Stripe,进行Radar,以及提供这些信息给Stripe是否安全)。
2. 使用校验检查
当进行支付的时候,Stripe会将咱们提供的信息提交到发卡单位,发卡单位会对这些信息进行校验。但验证不经过时,此次支付就又可能就是一次欺诈。所以,强烈推荐收集: CVC,Postal code 和 billing address。这些都有助与帮助检测潜在的欺诈行为。
每一个Charge Object中都会含有校验信息. 具体见verification response。固然也能够在Dashboard中看到校验结果。
Card verification code check (CVC) Businesses are not permitted to store the CVC。因此通常而言,CVC只会经过物理丢失,或者在不安全的网站输入而被盗。
Address verification (AVS) AVS checks determine whether these pieces of information match the billing address on file with the card issuer。Radar 默认阻止不经过 postal code verification的支付。注意,若是使用了billing address verification,当用户填写的地址和用户申请信用卡时候的地址不一致,将没法完成支。
若是你有多个商业系统,建议使用不一样的帐号。Stripe提供了Multiple Account的功能来设置不一样的帐号。
在平时咱们使用绑定信用卡到支付平台的时候,会先进行少许金额的支付,好比一美圆,再进行自动退款,应该是为了通知信用卡持有者有人正在使用他的卡进行支付。
线上欺诈的类型。线上欺诈和对实体商业的欺诈有着根本上的不一样,由于在线上你很难肯定你实际销售的对象是谁。在接受线上交易是,你很是有必要知道有哪些欺诈方式。
识别潜在的欺诈。Stripe为咱们给出了一些建议,让咱们可以尽可能提早识别出潜在的欺诈。固然,Stripe的Rada功能也会自动识别出具备高欺诈风险的信用卡付款。以下为内容概要,更加详细的内容以官网内容为准。
对于反常的订单(订单金额特别大, 量特别大), 则须要特殊处理, 好比经过电话确认或者email确认之类的.
能够在交易流程中增长一个支付审核的流程,并使用两步支付的方法来进行实现。
data-zip-code="true"
to the above and make use of Radar's built-in rules to decline payments that fail verification.<script src="https://js.stripe.com/v3/"></script>
退款一旦发生, 将不会被中止。
所有退款
Map<String, Object> params = new HashMap<>(); params.put("charge", stripeToken); Refund refund = Refund.create(params);
部分退款
Map<String, Object> params = new HashMap<>(); params.put("charge", stripeToken); params.put("amount", 1000); Refund refund = Refund.create(params);
可使用charge.refund.updated
监控退款事件。若是charge是经过Customer的方式发生的,且在Customer中含有email信息,则在退款发生时,会发送消息给用户。
支付精度。在实现支付的时候,咱们须要关注Stripe平台的精度。
支付单位
默认使用最小单位, 如美圆用美分.对于零位小数货币,仍然以整数形式提供金额,但不乘以100。例如,要收取500英镑,只需提供500英镑的金额。(零位小数货币列表supported charge currencies)
最小支付金额
因为Stripe的处理费结合了一小部分固定金额和百分比,所以在使用Stripe建立费用时强制执行最低金额。这能够确保您不会因收费而损失金钱。您能够收取的最低金额取决于支付的银行账户结算货币。
最大支付金额
The only limit to the maximum amount you can charge a customer is a technical one. The amount value supports up to eight digits (e.g., a value of 99999999 for a USD charge of $999,999.99).
须要设置美圆的最大支付值为 $999,999.99 . 或者设置一个其余的值.
防止Stripe IP没法访问。
由于调用接口须要访问到Stripe的服务器,以及在利用webhooks接受支付回调时,接受Stripe服务器的访问。所以须要在系统里面确保Stripe服务器的可访问性。
为了可以及时的知道Stripe Ip的变更,能够订阅Stripe的API announce mailing list
使用webhooks能够监控支付的一些触发事件。
这里的介绍中尚未涉及到其余的支付方式,事实上Stripe支持很是多的支付方式,都已经支持支付宝和微信,设置还支持比特币支付。Stripe有一个Payment Intents API能够对多种支付方式作更好的实现。
善用Card和Customer功能,能够方便对支付的管理和提供用户的体验。这里的内容都比较多,暂时就不展开详细介绍了。
Stripe提供帐单的功能对指定用户进行周期性的收费,这就能够用与实现相似会员自动续费的功能了。
除非你有PCI的认证,不然请不要在数据库中保存用户的信用卡信息,甚至让这些信息通过你的服务器。
根据苹果公司的规定,出售数字化内容须要使用应用内购买,好比电子游戏附带的游戏级别和应用给予用户的虚拟物品。而对于像衣服这样的实物,则容许使用像Stripe 这样的其余支付方案。使用Stripe支付,就能够不用给苹果交高额的费用。