Stripe 串接初體驗


Posted by Nacho on 2020-11-15

前言

  • 理解用 Stripe 完成信用卡支付的流程
  • 摘要紀錄 Rails 串接 stripe 信用卡支付的概念
  • 紀錄其他支付需要注意的部分

常見的卡片交易過程

  1. checking card details
    格式上的檢查,不保證卡片本身是合法的
    customer authentication (選擇性)
    有些銀行會要求顧客進行交易前再做一個階段的驗證
  2. Authorization
    銀行確認顧客帳戶有足夠的錢,並準備將金額撥款給賣家
  3. capture
    客戶的銀行將前移轉到賣家的帳戶

Stripe 客製化交易流程概念

Stripe 線上支付流程

  • Stripe 使用 PaymentIntent 來代表顧客的支付資料集合(一個很大包的JSON),裡面有紀錄付款進度、支付狀態、訂單金額、收件人信箱等。
  • 其實整個支付流程大概都圍繞在 PaymentIntent 的變化,而要理解支付流程就需要先理解這張圖。
  • 從左上方開始講起
    1. 顧客進到支付頁面,假設是一個購物車的畫面,購物車已經有確認待購買的商品
    2. 它啟動 stripe 支付,前台將訂單的資訊送往後端
    3. 後端將方才的訂單資訊打給 Stripe API (post: /v1/payment_intent)
    4. Stripe 產生了該顧客的 PaymentIntent 並回傳給後端
    5. 後端再將 PaymentIntnet 裡的 client_secret 取出並傳給前端
    6. 前端收到 client_secret 就可以建立支付的介面,以卡片來說就是建立填寫信用卡的表單欄位;顧客提供卡片的資料,並確認付款
    7. 前端直接將卡片資料與 client_secret 傳送給 Stripe
    8. Stripe 為我們完成支付的後續任務,比方像驗證卡片是否合法、帳戶是否有足夠的錢等等
    9. 支付成功回傳有 status 是 'succeeded' 的 PaymentIntent

Stripe 信用卡支付實作

程式語言:Ruby
適用專案:Rails Dev

前置準備

  • 首先,註冊一個 Stripe 的官方帳號,並為開發環境建立 key,要產生這兩個key(secret_key 和 publishable_key)
  • 在 Gemfile 裡安裝 gem 'stripe' 並 bundle install
  • 在 config/ 底下產生 stripe.yml
development:
  secret_key: xxxxxxxx
  publishable_key: xxxxxxxxxx
  • 在 config/initializers/ 底下建立一個 stripe.rb,如此在初次檔案載入時就可以一併將 key 的值給塞入 config file
stripe_config = Rails.application.config_for(:stripe)

Rails.configuration.stripe = {
    :publishable_key => stripe_config["publishable_key"],
    :secret_key      => stripe_config["secret_key"]
}

Stripe.api_key = stripe_config["secret_key"]

前端部分

  • 在 view/layout/application.html.erb 的 head 標籤中加入
<script src="https://js.stripe.com/v3/"></script>
  • 在前端取得 publishable_key ,我的做法是寫在某個 html.erb 並在每次用戶的 request 中跟著 layout 一起渲染到用戶的畫面上
  • 在支付的顯示頁面的檔案中,這是為了取得 client_secret 後,stripe 會在產生卡片支付的表單,並綁定在 card-element 的 id。延續原系統支付頁面的設計,所以調整了它的結構如下
<form id="payment-form">
  <div><!-- 其他支付表單 -->></div>
  <div id="aboard_credit_card">
    <div id="card-element">
      <!-- Stripe 在此插入卡號、月、年等需使用者填入的欄位-->
    </div>
    <div id="card-errors" role="alert">
      <!-- Stripe 顯示錯誤訊息的地方 -->    
    </div>
  </div>
  <div id="aboard-submit">
    <button id="stripe-payment-submit">確認付款</button>
  </div>
</form>
  • 在 assets/javascripts/ 下新增一個 client-stripe.js,並在 application.js 內引入。
  • client-stripe.js 其實就是對應先前流程圖前端處理的部分:
    1. 建立用戶的付款 UI ,支付形式為 card 。參考範例L37-65
    2. 像後端取得 client_secret,這裡我是寫一個 ajax 將用戶的訂單資料傳到後台。待取得 client_secret 後再建立用戶付款 UI 。參考範例L10-35
    3. 預防用戶可能會輸入錯誤資訊,因此,要監聽 卡片元件的變化,並將 error message 顯示在 card-errors。參考文件Collect card detail最下方
    4. 用戶按下確認按鈕。這裏需要透過 stripe 的 confirmCardPayment 方法,將卡片資訊直接傳給 Stripe server(注意這邊會略過後端),並等候paymentIntent 的 callback。參考範例L71-121。另外,也可以在這個階段加入像付款者的帳單資訊、指定收據寄發的信箱等資料。參考confirmCardPayment
    5. 接續前一步,將得到的 paymentIntent 透過另一支 ajax 打給後端存取 paymentIntent

後端部分

後端部分,依據不同系統的架構有不同的處理方式,這裏僅紀錄實作的概念。依據先前提到的流程圖,在後端最少要有兩支 API

  • /stripe/get_secret,將前端收到的訂單資訊打給 Stripe API(第三步驟)
    • 這裏要用到 Stripe::PaymentIntent.create()
  • /stripe/webhook,在支付啟動期間,用來接收 Stripe 提供的 Event 物件
    • webhook 是需要到 Stripe 後台做設定的
    • 一旦設定,stripe 會自動在發送 Event 物件給後端,因為 Event 物件上有不同的狀態,後端可以參閱官方文件,再決定要在哪幾種狀態下實作不同的行為

webhook 是讓你的網站可以與對方網站保持溝通的方式,換句話說,webhook 就好像是一個電話號碼,stripe 會打這支專線來通知目前你 Stripe 帳號上正在發生的活動。
實際上,活動就是 stripe 提供的 Event 物件,並在每一次有發生支付變化後會收到這個物件。
https://stripe.com/docs/webhooks

串接需要注意的點

  • 網路穩定,否則無法產生信用卡介面
  • webhook 要進到 stripe 後台去開這個功能
  • 測試卡輸入會自動跳出 zip code 欄位,這是正常流程
  • 測試站、與產品環境要有stripe.yml,deploy.rb 要 link 這個檔案 stripe.yml(使用capistrano)
  • 測試環境不會寄信
  • 測試卡號參考 https://stripe.com/docs/testing#cards

值得參考

Github readme
https://github.com/stripe-samples/accept-a-card-payment
官網/ stripe支付整合
https://stripe.com/docs/payments/accept-a-payment?integration=elements
handle Stripe webhooks in Rails
https://www.grok-interactive.com/blog/handling-stripe-webhooks-in-rails/
How To Securely Handle Webhook Events From Stripe In Ruby On Rails Application?
https://www.botreetechnologies.com/blog/how-to-securely-handle-webhook-events-from-stripe-in-ruby-on-rails-application


#Stripe #Rails #Webhook #金流串接 #信用卡







Related Posts

讓電腦看得懂人類語言的第一步 - 詞向量

讓電腦看得懂人類語言的第一步 - 詞向量

[筆記] HTTP 協定

[筆記] HTTP 協定

Wampserver如何安裝舊版本php

Wampserver如何安裝舊版本php


Comments