Stripe開發使用指南--國際支付(含支付寶)

troyyang發表於2018-01-29

前段時間,因為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>
複製程式碼

就這麼幾行程式碼,我們就已經實現了客戶端所有事:

image

真的是超級簡單,但是這種方式是基於信用卡支付的介面,已經可以滿足一半的支付方式,對於其他的三方支付,比如3D secure, 支付寶,微信,甚至比特幣,Stripe為我們提供了其他方式,等下我就使用支付寶來舉例。

註冊 Stripe 賬號

和註冊支付寶賬號一個道理,首先註冊賬號,然後繫結自己銀行卡,BUT, 就像前面提到的,不支援中國,所以就算註冊成功,也沒法啟用,也就沒法收款。

Stripe開發使用指南--國際支付(含支付寶)

對於中國商家怎麼辦呢,我能想到的就只有這幾個辦法:

  • 自己去支援國家去辦理張銀行卡
  • 使用國外的朋友銀行卡
  • 使用Atlas

對於Jason來說,因為他是英國人,所以他可以建立他的主賬號,然後新增我的stripe賬號到他team memeber賬號列表中,這樣我就可以訪問他賬戶下所有開發者需要的許可權。邀請成功後,Dashboard頁面

兩個階段

Stripe有兩種模式,一個是測試模式(Test Mode),一個是生產模式(Live Mode),測試模式下產生的金錢交易都只用於測試,當所有測試通過後即可切換為Live模式。唯一的不同就是Publishable keySecret key, 一會我們會用到這兩個值。

image

交易流程

Stripe有幾個概念用於整個交易階段和狀態:

image

建立 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)

image

舉個支付寶的栗子

服務端 (Serverless)

以AWS的Lambda + API gateway為例, 其中,前者是用來定義API, 後者是做路由。

image

image

image

建立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

文章開頭那段

的整合程式碼就是使用的checkout方式,非常簡單。整合程式碼直接幫你完成了客戶端的部分,服務端只需要定義好source.chargeable的鉤子API 就好了。

在做支付寶開發的時候,發現可以直接使用Checkout的方式:

<form action="https://xxx.execute-api.eu-central-1.amazonaws.com/stripepayment/xxx" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="pk_test_xxx"
    data-amount="30000"
    data-name="myenglishtutor.eu"
    data-label="Pay With Alipay"
    data-description="30 days"
    data-image="/images/logo.png"
    data-locale="auto"
    data-alipay="auto"
    data-currency="usd">
  </script>
</form>
複製程式碼

但是總是得到這個錯誤:

Unrecognized request URL (POST: /v1/alipay/send_sms). Please see https://stripe.com/docs or we can help at https://support.stripe.com/.
複製程式碼

image

發郵件給Stripe support team得到的結果是為了以後的擴充套件,Stripe不再提供alipay的checkout方式, 無奈,只得使用下面的方式。

Stripe.js & Elements

當然對於如果你覺得Checkout的方式整合度太高,不夠靈活,那Stripe.js是你最好的選擇。

Stripe.js其實就是客戶端的一個JS核心類庫,Elements是它的UI類庫,其實上面的Checkout程式碼就是Stripe使用兩者給我們封裝好了的,避免我們直接接觸敏感資訊,但是其實質都是一樣的,都是用來建立source。這裡就直接貼出客戶端的程式碼了(這裡沒有用到Elements做UI,因為就是一個按鈕支付,太簡單,所以沒用到):

var stripe = Stripe('pk_live_xxxx');

function alipay(amount) {
    showLoading();
    stripe.createSource({
        type: 'alipay',
        amount: parseInt(amount),
        currency: 'gbp', // usd, eur,
        redirect: {
            return_url: 'https://xxx.eu/pay/result.html'
        },
    }).then(function (response) {
        hideLoading();
        if (response.error) {
            alert(response.error.message);
        }
        else {
            processStripeResponse(response.source);
        }
    });
}

function processStripeResponse(source) {
    window.location.href = source.redirect.url;
}
複製程式碼

image

這裡需要注意幾點:

  • currency 必須是Stripe賬號所在地貨幣,也就是繫結的銀行卡所在地,因為Jason是英國人,所以必須使用gbp(這裡愚蠢如我的犯了一個常識錯誤,一直以為英國也是歐盟的,所以使用eur,結果怎麼也不對,直接哭暈在廁所)
  • return_url指向的是當使用者重定向到我們常見的支付寶支付頁面後,跳轉回支付完成的頁面,在這個返回頁面中,因為支付寶是同步完成支付的,所以我們可以去查詢charge.succeeded的狀態來判定是否使用者支付是否完成。

當一切OK,點選支付按鈕,就會跳轉到支付寶支付頁面(其他支援的三方平臺也可以),如下:

image

原文轉自troyyang.com/2018/01/21/…

相關文章