初步認識 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支付,就能夠不用給蘋果交高額的費用。

相關文章
相關標籤/搜索