前段時間,由於Jason讓我幫忙把Stripe支付集成到他我的網站上去,讓我有機會接觸到支付系統開發,同時也由於苦於沒有找到太多中文方面相關文檔介紹,因此作個總結,也方便之後有須要的同窗。html
第一次據說Stripe仍是在幾個月前的一個新聞上了解到,大體說的是美國總統都在使用它,極有可能成功下一個Paypal。這麼受歡迎的一個支付平臺到底有什麼好處呢?我粗略蒐集了一下:程序員
重點說下第二點,什麼意思呢,就是說客戶可使用人民幣支付,若是商家(收款方)是美國的銀行的話,就自動轉成美圓,是英國的銀行就自動轉爲英鎊!(惋惜暫時不支持商家是中國(但Stripe也可提供解決方案,就是使用Atlas去建立一個美國的代理公司))web
而對於咱們程序員的話,固然最關心第一條,由於他的宗旨就是開發極簡,對開發人員超級友好!至於多友好呢,請往下看。api
<!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>
複製代碼
就這麼幾行代碼,咱們就已經實現了客戶端全部事:bash
真的是超級簡單,可是這種方式是基於信用卡支付的界面,已經能夠知足一半的支付方式,對於其餘的三方支付,好比3D secure, 支付寶,微信,甚至比特幣,Stripe爲咱們提供了其餘方式,等下我就使用支付寶來舉例。服務器
和註冊支付寶帳號一個道理,首先註冊帳號,而後綁定本身銀行卡,BUT, 就像前面提到的,不支持中國,因此就算註冊成功,也無法激活,也就無法收款。 微信
對於中國商家怎麼辦呢,我能想到的就只有這幾個辦法:less
對於Jason來講,由於他是英國人,因此他能夠建立他的主帳號,而後添加個人stripe帳號到他team memeber帳號列表中,這樣我就能夠訪問他帳戶下全部開發者須要的權限。邀請成功後,Dashboard頁面ide
Stripe有兩種模式,一個是測試模式(Test Mode),一個是生產模式(Live Mode),測試模式下產生的金錢交易都只用於測試,當全部測試經過後便可切換爲Live模式。惟一的不一樣就是Publishable key 和 Secret key, 一會咱們會用到這兩個值。 測試
Stripe有幾個概念用於整個交易階段和狀態:
使用本身的Publishable key來建立一種source(好比Cards, 3D Secure, 支付寶,甚至比特幣等), 建立source完了後,就會獲得一個用於交易的Token或者是一個跳轉到其餘支持的三方支付平臺(好比支付寶支付)頁面等待用戶支付。當用戶支付(或者取消支付)完成,自動跳轉回到指定結果頁面。用戶支付頁面結束後,可能會獲得三個狀態:
當用戶支付成功後,此時在Stripe端的支付狀態變爲source.chargeable,意思就是受權成功了,你能夠在我支付寶平臺上扣錢啦,因此,此時咱們還須要使用Secret key來建立Charge來完成,官方推薦的是使用webhooks來捕捉狀態,而且完成Charge的建立。當Charge完成後,整個支付完成,會獲得一個charge.succeeded的狀態。
Webhooks 裏提供了幾十種狀態,全部這些狀態都會註冊到Stripe裏一個叫webhooks事件鉤子的地方,咱們能夠指定不一樣事件的觸發時,轉發數據到某個咱們本身搭建好的Web Api上。(下圖是咱們的服務器end point, 由於咱們沒有用到服務器,使用的是亞馬遜lambda作一個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 });
}
});
};
複製代碼
多種實現方式:
文章開頭那段