前段時間,因為Jason讓我幫忙把Stripe支付整合到他個人網站上去,讓我有機會接觸到支付系統開發,同時也因為苦於沒有找到太多中文方面相關文件介紹,所以做個總結,也方便以後有需要的同學。
關於Stripe支付
第一次聽說Stripe還是在幾個月前的一個新聞上了解到,大致說的是美國總統都在使用它,極有可能成功下一個Paypal。這麼受歡迎的一個支付平臺到底有什麼好處呢?我粗略蒐集了一下:
- 一條程式碼讓你網站支援繁瑣的國際支付功能。(對於創業公司,再合適不過)
- 向全球化業務擴充會成為Stripe的機會。即使支付貨幣不同、方法不同,Stripe都能打通各自的渠道,讓全球化交易不受支付阻礙。
- 市值超過90億美元,和Tweeter,Lyft,Best Buy等以及國內的 Alipay, WeChat等有合作
重點說下第二點,什麼意思呢,就是說客戶可以使用人民幣支付,如果商家(收款方)是美國的銀行的話,就自動轉成美元,是英國的銀行就自動轉為英鎊!(可惜暫時不支援商家是中國(但Stripe也可提供解決方案,就是使用Atlas去建立一個美國的代理公司))
而對於我們程式設計師的話,當然最關心第一條,因為他的宗旨就是開發極簡,對開發人員超級友好!至於多友好呢,請往下看。
最簡潔支付
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stripe Checkout</title>
</head>
<body>
<form action="/your-server-side-code" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="[Publishable key]"
data-amount="999"
data-name="troy yang"
data-description="Widget"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto"
data-zip-code="true"
data-currency="eur">
</script>
</form>
</body>
</html>
複製程式碼
就這麼幾行程式碼,我們就已經實現了客戶端所有事:
真的是超級簡單,但是這種方式是基於信用卡支付的介面,已經可以滿足一半的支付方式,對於其他的三方支付,比如3D secure, 支付寶,微信,甚至比特幣,Stripe為我們提供了其他方式,等下我就使用支付寶來舉例。
註冊 Stripe 賬號
和註冊支付寶賬號一個道理,首先註冊賬號,然後繫結自己銀行卡,BUT, 就像前面提到的,不支援中國,所以就算註冊成功,也沒法啟用,也就沒法收款。
對於中國商家怎麼辦呢,我能想到的就只有這幾個辦法:
- 自己去支援國家去辦理張銀行卡
- 使用國外的朋友銀行卡
- 使用Atlas
對於Jason來說,因為他是英國人,所以他可以建立他的主賬號,然後新增我的stripe賬號到他team memeber賬號列表中,這樣我就可以訪問他賬戶下所有開發者需要的許可權。邀請成功後,Dashboard頁面
兩個階段
Stripe有兩種模式,一個是測試模式(Test Mode),一個是生產模式(Live Mode),測試模式下產生的金錢交易都只用於測試,當所有測試通過後即可切換為Live模式。唯一的不同就是Publishable key 和 Secret key, 一會我們會用到這兩個值。
交易流程
Stripe有幾個概念用於整個交易階段和狀態:
建立 Source
使用自己的Publishable key來建立一種source(比如Cards, 3D Secure, 支付寶,甚至比特幣等), 建立source完了後,就會得到一個用於交易的Token或者是一個跳轉到其他支援的三方支付平臺(比如支付寶支付)頁面等待使用者支付。當使用者支付(或者取消支付)完成,自動跳轉回到指定結果頁面。使用者支付頁面結束後,可能會得到三個狀態:
- source.chargeable 使用者授權(支付)成功
- source.failed 使用者拒絕授權(支付)
- source.canceled 超時支付
建立 Charge
當使用者支付成功後,此時在Stripe端的支付狀態變為source.chargeable,意思就是授權成功了,你可以在我支付寶平臺上扣錢啦,所以,此時我們還需要使用Secret key來建立Charge來完成,官方推薦的是使用webhooks來捕捉狀態,並且完成Charge的建立。當Charge完成後,整個支付完成,會得到一個charge.succeeded的狀態。
使用 webhooks
Webhooks 裡提供了幾十種狀態,所有這些狀態都會註冊到Stripe裡一個叫webhooks事件鉤子的地方,我們可以指定不同事件的觸發時,轉發資料到某個我們自己搭建好的Web Api上。(下圖是我們的伺服器end point, 因為我們沒有用到伺服器,使用的是亞馬遜lambda做一個Serverless)
舉個支付寶的栗子
服務端 (Serverless)
以AWS的Lambda + API gateway為例, 其中,前者是用來定義API, 後者是做路由。
建立Charge程式碼:
'use strict';
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
exports.handler = (event, context, callback) => {
console.log("request: " + JSON.stringify(event));
let stripeData = event.data.object;
stripe.charges.create({
amount: stripeData.amount,
source: stripeData.id,
currency: stripeData.currency || 'usd',
description: 'My Englishtutor 30 days' || ('Stripe payment ' + event.id),
}, function(err, charge) {
if (err && err.type === 'card_error') {
context.fail(new Error(err.message));
}
else if (err) {
context.fail(err);
}
else {
context.succeed({ status: charge.status, success: true });
}
});
};
複製程式碼
客戶端 (Web)
多種實現方式:
Checkout
文章開頭那段