綠界ECPAY平台串接 – Payment API

閱讀時間約 14 分鐘

※ 在前端畫面顯示ECPay:

● 優化前端:views → index.ejs

<!-- 新增按鈕 -->
<div>
<button>綠界支付</button>
</div>


● 在Vue 組件的資料定義中,新增buyItem來存儲購買的項目和數量:javascripts → index.js

createApp({
data() {
return {
serverDomain: 'http://localhost:30000',
buyItem: {}, //{"1":8, "2": 5/"id":"amount"}
products: []
}
},

}).mount('#app');

程式碼解說:

  • serverDomain
    • serverDomain: 'http://localhost:30000' 用於設定伺服器的域名,這樣可以在其他方法中使用這個變數來構建請求 URL。
  • buyItem
    • buyItem: {} 初始化為一個空物件,用於存儲購買的項目及其數量。例如,{"1":8, "2":5} 表示產品 ID 為 1 的項目購買了 8 件,產品 ID 為 2 的項目購買了 5 件。
  • products
    • products: [] 初始化為一個空陣列,用於存儲產品的詳細信息。這個陣列會在後續的操作中被填充,例如從伺服器獲取產品列表。


● 使用 {{ buyItem }} ,在模板中顯示資料:views → index.ejs

<body>
<div id="app">
{{buyItem}}
</div>
</body>

● 使用v-model ,讓產品資料即時更新和顯示:views → index.ejs

  <td>
<input v-model="buyItem[product.id]" type="number" min="0" max="100" step="1">
</td>


● 結果:

raw-image


● 根據購買項目生成詳細的產品資料:javascripts → index.js

createApp({
data() {
return {
buyItem: {}, //{"1":8, "2": 5/"id":"amount"}
products: []
}
},

methods: {
getItemDetailByBuyItem() {
return Object.entries(this.buyItems).map(([id, amount]) => ({
productId: Number(id),
price: this.products.find(product => product.id === Number(id)).price,
amount: Number(amount)
})); //[{productId:1, price: 100, amount: 9}]
}
}

}).mount('#app');

程式碼解說:

getItemDetailByBuyItem 方法:
  • 這個方法返回一個新陣列,陣列中的每個項目都包含購買的產品詳情(productId、price 和 amount)。

Object.entries(this.buyItems)
  • 將 buyItems 物件轉換為一個由鍵值(keyvalue)組合的陣列。
  • buyItems 物件結構類似 { "1": 8, "2": 5 },轉換後的陣列為 [ ["1", 8], ["2", 5] ]。在這個陣列中,每個元素都是一個陣列,其中包含兩個值:第一個值是鍵(產品ID),第二個值是對應的值(購買數量)。

  • .map(([id, amount]) => ({...}))
    • 使用 map 方法遍歷 buyItems 的每一個鍵值對(即產品 ID 和購買數量)。
    • 把每個鍵值對轉換成一個包含產品細節的物件。
  • Number(id)
    • 將產品 ID 從字串轉換為數字。

this.products.find(product => product.id === Number(id)).price

  • 在 products 陣列中尋找對應 ID 的產品,並獲取其價格。

Number(amount)

  • 將購買數量從字串轉換為數字。

●發送付款請求:javascripts → index.js

createApp({
data() {
return {
buyItem: {}, //{"1":8, "2": 5/"id":"amount"}
products: []
}
},
//打API
async sendPayment(url, date) {
try {
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
cors: 'no-cors',
body: JSON.stringify(data)
})
.then((res) => {

            if (res.ok) return res.json();

            return res.json().then((json) => Promise.reject(json));

          });

        return result;


} catch (e) {
console.error('~ file: index.js ~ line 32 ~ sendPayment ~ e', e)
throw new Error(e)
}
}

}

}).mount('#app');

程式碼解說:

  • 非同步函數 (async):
    • 這是定義了一個名為 sendPayment 的非同步函數,表示在函數內部可以使用 await 關鍵字來等待非同步操作完成。
  • fetch 方法:
    • 用於向指定的 URL 發送 HTTP 請求。
    • 用於發送一個 POST 請求,並將 data 作為請求的主體。
  • 請求設置:
    • method: 'POST':指定請求方法為 POST。
    • headers: { 'Content-Type': 'application/json' }:設定請求標頭,表示請求內容的格式是 JSON。
    • cors: 'no-cors':設定跨域請求策略。(no-cors:禁止跨域請求訪問某些資源。)
    • body: JSON.stringify(data):將 data 物件轉換為 JSON 字符串,並作為請求體發送。

處理回應:

.then((res) => { ... }):處理 fetch 方法返回的 Promise。

  • if (res.ok):檢查回應的狀態。如果 res.ok 為 true,表示請求成功,返回解析後的 JSON。
  • return res.json().then((json) => Promise.reject(json)):如果請求失敗,返回解析後的 JSON 並將其作為被拒絕的 Promise。
  • 錯誤處理 (try...catch):
    • 如果發送請求時出現錯誤,會在控制台中記錄錯誤訊息,並拋出一個新的錯誤。

● ECPay支付:javascripts → index.js

async ECPay() {

//檢查 buyItems 是否為空

if (!Object.keys(this.buyItems).length) return alert('沒有選項')
// 處理 items 陣列中的每個產品詳細內容
const items = this.getItemDetailByBuyItem();
console.log('~ file: index.js ~ line 50 ~ ECPay ~ items', items);
//發送支付請求
const result = await this.sendPayment(`${this.serverDomain}/orders/create`),
{
paymentProvider: "ECPAY",
paymentWay: "CVS",
contents: items,
});
console.log(result);
}
}

程式碼解說:

非同步函數 (async)
  • async 關鍵字表示這是一個非同步函數,可以使用 await 關鍵字來等待非同步操作完成。

檢查 buyItems 是否為空

if (!Object.keys(this.buyItems).length) return alert('沒有選項');
    • 使用 Object.keys(this.buyItems) 來獲取 buyItems 物件的所有鍵(即項目ID)的陣列。
    • Object.keys(this.buyItems).length 返回這個陣列的長度。如果 buyItems 中沒有任何項目,這個長度將為 0。
  • 條件判斷
    • if (!Object.keys(this.buyItems).length) 判斷 buyItems 是否為空。如果是空的(長度為0),則條件為真。
  • 提示訊息
    • 如果條件為真,則執行 alert('沒有選項'),彈出一個提示框,顯示訊息「沒有選項」。

處理購物車項目

const items = this.getItemDetailByBuyItem();
console.log('~ file: index.js ~ line 50 ~ ECPay ~ items', items);
  • 調用 getItemDetailByBuyItem 方法,將 buyItems 中的每個項目轉換為詳細的產品資訊物件,並將結果賦值給 items 變數。
  • 使用 console.logitems 內容輸出到控制台以便檢查。

發送支付請求

const result = await this.sendPayment(`${this.serverDomain}/orders/create`, {
paymentProvider: "ECPAY",
paymentWay: "CVS",
contents: items,
});
console.log(result);
  • 使用 await 調用 sendPayment 方法,向 serverDomain/orders/create 發送一個支付請求。
  • sendPayment 方法會向 ${this.serverDomain}/orders/create 這個 URL 發送一個 HTTP POST 請求,包括支付提供者(paymentProvider)、支付方式(paymentWay)和購物車內容(contents)。
  • 將支付請求的結果賦值給 result 變數,並輸出到控制台。

● ECPay支付綁定到Button:views → index.ejs

 <!-- 新增按鈕 -->
<div>
<button @click="ECPay">綠界支付</button>
</div>

程式碼解說:

@click="ECPay" 表示當按鈕被點擊時會觸發 ECPay 方法,包括檢查購物車項目、獲取購買項目詳細資訊並發送支付請求。

@clickVue.js 中的事件綁定語法,等同於 v-on:click。它用來監聽按鈕的點擊事件,並在點擊時執行指定的方法。



● 成功畫面:

1.前端畫面

raw-image

2.MySQL - ORDERS畫面

raw-image







    全端網頁開發專業知識分享
    留言0
    查看全部
    發表第一個留言支持創作者!
    ※ 綠界科技API平台: https://www.ecpay.com.tw/ ● 進到開發者中心: ● API串接規格文件: ● 使用SDK來串接Node.JS 的WEB SERVICE: ● 綠界 全方位(All In One)金流介接Node.js 第一版: 載點:htt
    ※ 利用transactionHandler將資料寫入database ● 在orderController.ts檔案中使用 try...catch 區塊:  try { } catch (err) { // 處理錯誤 res.status(500).json({ errors: e
    ※ 在orderController.ts檔案中定義createOrder:  public createOrder: IOrderController['createOrder'] = (req, res, _next) => { let { paymentProvider, paym
    ※ 訂單開立流程 → 完結的流程 前端資料驗證。 將商品的數量寫入(預扣)→ id。 利用ID去打第三方金流的API來產生第三方金流的訂單。 當使用者繳完錢之後,第三方金流他會打我們提供的update資訊的API。 ※ 從前端需要傳入的資料: 商品ID、商品數量、使用哪個payment
    ※ 路由設定: 在routes資料夾中,建立product.ts: ※ 設置產品相關的路由: 1.匯入模組: import express from 'express'; import { ControllerContext } from '@/manager/controllerM
    ※ 建立一個管理者的資料夾,負責建立不同的管理 — manager: ※ 在manager資料夾中,建立modelManager.ts: ※ 設定資料庫模型的管理: 匯入模組: import { IProductModel, ProductModel } from "@/model/prod
    ※ 綠界科技API平台: https://www.ecpay.com.tw/ ● 進到開發者中心: ● API串接規格文件: ● 使用SDK來串接Node.JS 的WEB SERVICE: ● 綠界 全方位(All In One)金流介接Node.js 第一版: 載點:htt
    ※ 利用transactionHandler將資料寫入database ● 在orderController.ts檔案中使用 try...catch 區塊:  try { } catch (err) { // 處理錯誤 res.status(500).json({ errors: e
    ※ 在orderController.ts檔案中定義createOrder:  public createOrder: IOrderController['createOrder'] = (req, res, _next) => { let { paymentProvider, paym
    ※ 訂單開立流程 → 完結的流程 前端資料驗證。 將商品的數量寫入(預扣)→ id。 利用ID去打第三方金流的API來產生第三方金流的訂單。 當使用者繳完錢之後,第三方金流他會打我們提供的update資訊的API。 ※ 從前端需要傳入的資料: 商品ID、商品數量、使用哪個payment
    ※ 路由設定: 在routes資料夾中,建立product.ts: ※ 設置產品相關的路由: 1.匯入模組: import express from 'express'; import { ControllerContext } from '@/manager/controllerM
    ※ 建立一個管理者的資料夾,負責建立不同的管理 — manager: ※ 在manager資料夾中,建立modelManager.ts: ※ 設定資料庫模型的管理: 匯入模組: import { IProductModel, ProductModel } from "@/model/prod
    你可能也想看
    Google News 追蹤
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    ※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
    Thumbnail
    ※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
    Thumbnail
    一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
    Thumbnail
    在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
    Thumbnail
    本文介紹瞭如何在後端系統開發時設計不同表單的簽核流程,包括請假表單和採購表單。以及如何動態生成簽核表單,並建立簽核節點。另外還介紹瞭如何利用繼承來簡化簽核流程的設定。
    ※ 補充說明: ※ npm 常用指令: ◦ npm init–y:快速初始化一個新的 Node.js 並建立一個 package.json 文件的命令。 ◦ npm info 套件名稱 version:快速查詢指定 npm 套件的最新版本號。 ◦ npm install套件名稱:用來安裝
    Thumbnail
    平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
    Thumbnail
    Accept:用戶端能夠接收的內容類型。 Accept: text/plain, text/html Accept-Charset:瀏覽器可以接受的字元編碼集。 Accept-Charset: utf8 Accept-Encoding:指定瀏覽器可以支援的web伺服器返回內容壓縮編碼
    Thumbnail
    這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
    Thumbnail
    11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
    Thumbnail
    Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
    Thumbnail
    ※ 什麼是Web API API 就是後端開出來讓前端來用的介面,讓前端與後端可以溝通。 API流程: 終端使用者用任何一種裝置進入瀏覽器。 瀏覽器透過 API 向後端發出請求,請求查詢或修改資料。 後端透過 API 收到前端的請求後,取得資料並回應給前端。 前端渲染畫面,終端使用者
    Thumbnail
    ※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
    Thumbnail
    一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
    Thumbnail
    在前一篇我們已經成功地建立簽核表單及簽核節點並關聯回請假表單,而本篇會接著介紹如何管理簽核節點狀態並同步更新簽核表單狀態。
    Thumbnail
    本文介紹瞭如何在後端系統開發時設計不同表單的簽核流程,包括請假表單和採購表單。以及如何動態生成簽核表單,並建立簽核節點。另外還介紹瞭如何利用繼承來簡化簽核流程的設定。
    ※ 補充說明: ※ npm 常用指令: ◦ npm init–y:快速初始化一個新的 Node.js 並建立一個 package.json 文件的命令。 ◦ npm info 套件名稱 version:快速查詢指定 npm 套件的最新版本號。 ◦ npm install套件名稱:用來安裝
    Thumbnail
    平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
    Thumbnail
    Accept:用戶端能夠接收的內容類型。 Accept: text/plain, text/html Accept-Charset:瀏覽器可以接受的字元編碼集。 Accept-Charset: utf8 Accept-Encoding:指定瀏覽器可以支援的web伺服器返回內容壓縮編碼