初步认识 Stripe 支付

前言

这段时间在作支付相关的工做,因为业务主要是面向国外的用户,于是就接触了部分国外的支付支付相关的平台。接下来的内容主要是初步看了 Stripe 平台的文档所了解到的基本内容,后面会在使用的过程当中不断地进行完善。html

基本介绍和与其余支付平台的对比

什么是Stripe

Stripe - 基于API的便捷支付渠道 中对Stripe所提供的功能/产品给了较为不错的参考。前端

使用范围

在我写这篇博客之时(2019-04-07),stripe已经支持32个国家的使用,而我在查找资料的时候,看到的基本都是说25个国家。支持的国家(https://stripe.com/global)java

201904100303-stripe-business-contries.png

从列表中咱们能够看到,其实中国大陆是尚未被支持的。为了可以进行收钱,咱们须要一个在Stripe支持国家列表中的国家的银行帐号。若是中国的企业单位但愿使用的话,能够经过 StripeAtlas 建立一个美国的银行帐号。更多关于 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-flow.png

  1. 客户端将用户输入的信用卡信息(若是使用的其余的支付方式)发送到 Stripe 服务器。
  2. Stripe 服务器会对用户提交的信用卡信息进行检查校验,若是经过校验,则会返回一个token信息给客户端。
  3. 客户端将token和订单信息发送到服务器。
  4. 服务器会计算该订单的金额,并发送到Stripe服务器进行扣费。这里须要注意是,订单的金额是由后台计算决定的,不是由前端告知后台的。没有人会直接让客户决定商品的价格。
  5. Stripe返回交易结果给服务器端。
  6. 服务将交易结果返回给客户端。

测试帐号

为了方便咱们进行各类测试,Stripe 为咱们的测试提供了足够的测试帐号。

  1. Test card numbers and tokens 利用这里的各类类型的卡号能够进行完整流程的测试,token则能够方便后台进行独立的测试。这里提供的支付信息默认都是美国的,若是须要测试其余国家的支付,可使用国际测试帐号
  2. 3D Secure test card numbers and tokens
  3. Testing for specific responses and errors 测试异常和错误的测试卡号和token。
  4. Disputes 纠纷测试卡号和token。
  5. Rate limits
  6. Sources
  7. Redirect sources
  8. Webhooks

一步支付

后台获得支付使用的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。考虑是否须要将这些错误信息转化为平台的错误信息。须要注意的是,前端在获取受权的时候会有哪些错误返回,又应该如何进行展现。并非全部的交易失败均可以肯定具体的缘由,这些失败一般会返回 codegeneric,这时候最好让你的客户直接联系发卡银行,咨询具体缘由。

返回结果和失败缘由

...
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"
},
...

形成失败的缘由能够总结以下:

  1. 支付被发卡单位拒绝 (type:"issuer_declined")

    1. 信息错误,信用卡过时
    2. 有些信用卡会被限制使用的场景和国家,这些都会形成支付失败。
  2. Stripe 安全屏蔽(type: "blocked")

    1. Stripe 认为交易不安全
  3. 无效的API调用(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.createdcharge.dispute.closed 事件。

纠纷中须要提交的证据(后台开发中须要注意保留这些信息)

  • 网络日志,电子邮件通讯,货件跟踪号码和送货确认,先前退款或更换货件的证实等
  • 交易记录中应该保留重要的时间
  • AVS/CVC
  • 支付人支付时候的 IP address
  • 若是是虚拟产品, 须要设法记录用户是否已经下载了该产品, 或者是否已经使用了该服务.

防范纠纷和欺诈

为了防范纠纷和欺诈,咱们须要在开发的时候留意一些必要的操做。

1. 收集尽量多的支付信息

  • 客户的名称
  • 客户的email地址
  • CVC 数字
  • 完整的帐单地址和邮政编号
  • 运送地址 (若是和帐单地址不同的话)

有些信息时在前端获取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的功能来设置不一样的帐号。

在平时咱们使用绑定信用卡到支付平台的时候,会先进行少许金额的支付,好比一美圆,再进行自动退款,应该是为了通知信用卡持有者有人正在使用他的卡进行支付。

线上欺诈的类型

线上欺诈的类型。线上欺诈和对实体商业的欺诈有着根本上的不一样,由于在线上你很难肯定你实际销售的对象是谁。在接受线上交易是,你很是有必要知道有哪些欺诈方式。

  • Stolen cards 使用偷来的信用卡支付。当信用卡被盗刷卡的持有者经过银行追被盗刷的钱时, 咱们的产品或者服务是不会被返回的。这意味咱们要同时承担金钱和产品的亏损。
  • Overpayments 支付更多的钱
  • Alternative refunds
  • Marketplace 先支付过多的钱,而后找商家退款,并告知原来的卡已经关闭了,须要退到另外一张卡中。其实商家仍是能够退款到原来的卡中,用户只要联系银行便可将钱取出。所以咱们应该尽可能按原路返回退款。
  • Card testing 欺诈前对卡片可支付性进行测试。通常会在没有限制支付金额的网站进行测试。经过实现Captcha或者rate-limiting charges能够有助于和这种类型的欺诈作斗争。
  • Friendly 合法持卡作在进行交易的时候发起的纠纷。开发的时候应尽可能对信息进行校验,同时尽可能在用户支付的页面中明确地给出支付协议。

识别潜在的欺诈

识别潜在的欺诈。Stripe为咱们给出了一些建议,让咱们可以尽可能提早识别出潜在的欺诈。固然,Stripe的Rada功能也会自动识别出具备高欺诈风险的信用卡付款。以下为内容概要,更加详细的内容以官网内容为准。

  • General 这里提到的内容比较多。这里摘取其中的两点。1,若是用户在下单以后提出修改地址,应该要注意。由于这又多是为了跳过收获地址的校验。2,对于第一次交易,或者是特殊区域的交易能够作一个特殊的处理。
  • Physical goods 能够利用物理地址信息进行防范。
  • Digital goods or services 虚拟产品的防范须要尽量地去验证各类信息. 由于没有物流过程, 因此欺诈者能够快速并大量的进行消费。
  • Donations or crowdfunding 大概是由于会直接成功, 因此会常常被拿来测试卡的额度以及测试这张卡是否可用。应该经过 CAPTCHA 等方式减慢信用卡的使用速度。

对于反常的订单(订单金额特别大, 量特别大), 则须要特殊处理, 好比经过电话确认或者email确认之类的.

  • The order is much larger than normal, or is only for your most expensive products
  • The customer changed the shipping address after placing the order
  • The customer requested expedited shipping
  • The products ordered have a hight street resale value
  • The shipping destination is vastly different from the billing address or the card’s country of origin (e.g., billing address is Spain, shipping address is France)

能够在交易流程中增长一个支付审核的流程,并使用两步支付的方法来进行实现。

更加安全

  1. 使用Stripe的Radar[https://stripe.com/docs/radar]
  2. we highly recommend also having Checkout collect the user’s postal code, as address and postal code verifications help reduce fraud. Simply add data-zip-code="true" to the above and make use of Radar's built-in rules to decline payments that fail verification.
  3. 使用https协议
  4. To best leverage Stripe’s advanced fraud functionality, include this script on every page on your site, not just the checkout page. Including the script on every page allows Stripe to detect anomalous behavior that may be indicative of fraud as users browse your website. <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建立费用时强制执行最低金额。这能够确保您不会因收费而损失金钱。您能够收取的最低金额取决于支付的银行账户结算货币
mininum-charge-amounts.png

最大支付金额
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 IP没法访问
由于调用接口须要访问到Stripe的服务器,以及在利用webhooks接受支付回调时,接受Stripe服务器的访问。所以须要在系统里面确保Stripe服务器的可访问性。

为了可以及时的知道Stripe Ip的变更,能够订阅Stripe的API announce mailing list

其余

使用webhooks

使用webhooks能够监控支付的一些触发事件

更多支付方式

这里的介绍中尚未涉及到其余的支付方式,事实上Stripe支持很是多的支付方式,都已经支持支付宝和微信,设置还支持比特币支付。Stripe有一个Payment Intents API能够对多种支付方式作更好的实现。

善用Card和Customer

善用Card和Customer功能,能够方便对支付的管理和提供用户的体验。这里的内容都比较多,暂时就不展开详细介绍了。

帐单和发票

Stripe提供帐单的功能对指定用户进行周期性的收费,这就能够用与实现相似会员自动续费的功能了。

请不要随便保存用户的信用卡信息

除非你有PCI的认证,不然请不要在数据库中保存用户的信用卡信息,甚至让这些信息通过你的服务器。

IOS应用程序中若是可使用Stripe能够优先考虑Stripe

根据苹果公司的规定,出售数字化内容须要使用应用内购买,好比电子游戏附带的游戏级别和应用给予用户的虚拟物品。而对于像衣服这样的实物,则容许使用像Stripe 这样的其余支付方案。使用Stripe支付,就能够不用给苹果交高额的费用。

相关文章
相关标签/搜索