第三方金流串接 – 訂單開立和功能

更新於 發佈於 閱讀時間約 17 分鐘

※ 訂單開立流程

raw-image
  1. 前端資料驗證。
  2. 將商品的數量寫入(預扣)→ id。

※ 從前端需要傳入的資料:

商品ID、商品數量、使用哪個payment provider、 使用哪個payment way

※ 訂單Model(模型):model –––> order.ts

raw-image


定義了一個類別 OrderModel,所需要的訂單(Order)資料格式:

  • 用於處理與訂單相關的資料和操作。
import { Base } from "./base";
//PaymentProvider 介面:定義支付平台的結構。
export enum PaymentProvider {
ECPAY = "ECPAY",
PAYPAL = "PAYPAL"
}
//PaymentWay 介面:定義支付方式的結構。
export enum PaymentWay {
CVS = 'CVS',
PAYPAL = 'PAYPAL',
}
//OrderStatus 介面:定義訂單狀態的結構。
export enum OrderStatus {
WAITING = 'WAITING',
SUCCESS = 'SUCCESS',
FAILED = 'FAILED',
CANCEL = 'CANCEL',
}
//訂單的詳細資料
export interface OrderContent {
productId: number;
amount: number;
price: number;
}

//Order 介面定義了訂單的結構
export interface Order {
id: string;
total: number;
createdAt: Date;
updatedAt: Date;
paymentProvider: PaymentProvider;
paymentWay: PaymentWay;
status: OrderStatus;
contents: OrderContent[];
}



1.匯入模組

import { Knex } from "knex";
import { Base, IBase } from "./base";

程式碼解說:

  • 從 knex 模組匯入 Knex 類型,用於資料庫操作。
  • 因為order需要繼承base,所以從本地模組 ./base 匯入 Base 類別和 IBase 介面。

2.定義 Order 介面

export interface Order {
id: string;
total: number;
createdAt: Date;
updatedAt: Date;
paymentProvider: PaymentProvider;
paymentWay: PaymentWay;
status: OrderStatus;
contents: OrderContent[];
}

程式碼解說:

  • export interface Order {}:定義了一個 Order 介面,描述訂單的結構。
  • 定義訂單的結構,包括 ID、總金額、創建時間、更新時間、支付提供者、支付方式、訂單狀態和訂單內容。

3.用枚舉來定義支付平台、支付方式和訂單狀態的結構

export enum PaymentProvider {
ECPAY = 'ECPAY',
PAYPAL = 'PAYPAL',
}
export enum PaymentWay {
CVS = 'CVS',
PAYPAL = 'PAYPAL',
}
export enum OrderStatus {
WAITING = 'WAITING',
SUCCESS = 'SUCCESS',
FAILED = 'FAILED',
CANCEL = 'CANCEL',
}

程式碼解說:

  • 定義了三個枚舉:PaymentProvider、PaymentWay 和 OrderStatus,用於表示支付平台、支付方式和訂單狀態。

4.定義 OrderContent 介面:訂單的詳細資料

export interface OrderContent {
productId: number;
amount: number;
price: number;
}

程式碼解說:

  • 定義訂單內容,包括產品 ID、數量和價格。


5.定義訂單模型,對應到資料庫中的 orders 表:

export class OrderModel extends Base<Order> implements IBase<Order> {
tableName = 'orders';
//屬性會自動對應到資料庫表中的相應欄位
schema = {
id: 'id',
total: 'total',
createdAt: 'created_at',
updatedAt: 'updated_at',
paymentProvider: 'payment_provider',
paymentWay: 'payment_way',
status: 'status',
contents: 'contents',
}
}

程式碼解說:

  • 定義了一個類別 OrderModel,它繼承了 Base<Order>。這表示 OrderModel 類別將具有 Base 類別的所有屬性和方法,但它特別針對 Order 這個型別進行操作。
  • tableName 屬性:指定資料表名稱為 orders。
  • schema 屬性:定義資料表欄位與模型屬性的映射關係。

6.靜態方法 createModel:專門用來生成模型(model)

static createModel =
({ knexSql, tableName }: { knexSql: Knex; tableName?: string })
=> {
return new OrderModel({ knexSql, tableName });
}

程式碼解說:

  • 定義一個靜態方法 createModel,用於創建 OrderModel 實例。

7.建構函數

constructor({ knexSql, tableName }: { knexSql: Knex, tableName?: string }) {
super({ knexSql, tableName });
}

程式碼解說:

  • 初始化 OrderModel 實例:在創建 OrderModel 實例時,可以傳入資料庫連接(knexSql)和可選的資料表名稱(tableName),這些參數將被傳遞給基類的建構函數,以正確初始化基類的狀態。
  • 確保類別的繼承和初始化:通過調用 super,確保基類的建構函數被正確調用,使得 OrderModel 繼承了基類的屬性和方法。

8.定義一個有基礎(Base)介面中所有功能的訂單(Order)

export interface IOrderModel extends IBase<Order> {
create(orderData: Omit<Order, "id"> & { id?: string },
trx?: Knex.Transaction): Promise<Order | null>; }

程式碼解說:

  • 使用 export 導出這個介面,使其可以在其他模組中使用。
  • 使用 interface 關鍵字定義介面 IOrderModel。
  • extends IBase<Order> 表示 IOrderModel 繼承自 IBase<Order> 介面。
  • 這意味著 IOrderModel 會擁有 IBase<Order> 定義的所有屬性和方法。
  • 參數:
    • orderData:這是一個物件,類型是 Omit<Order, "id"> & { id?: string },表示 orderData 具有 Order 的所有屬性(除了 id),並且有一個可選的 id 屬性。
    • trx:這是一個可選的參數,類型是 Knex.Transaction,用於資料庫交易處理。
  • 返回值:這個方法返回一個 Promise,表示這個方法是非同步的。Promise 的值可以是 Order 或 null

9.IBase<Order>改成 IOrderModel:

export class OrderModel extends Base<Order> implements IOrderModel



※ 建立ORDER的CONTROLLER,處理訂單相關的 API 請求:controller –––> orderController.ts

raw-image

1.匯入模組:

import { IOrderModel, OrderContent, PaymentProvider, PaymentWay } from "@/model/order";
import { IProductModel } from "@/model/product";
import { NextFunction, Request, Response } from "express";
import { Knex } from "knex";

程式碼解說:

  • 從 @/model/order 和 @/model/product 匯入相關的介面和類型。
  • 從 express 匯入 NextFunction, Request 和 Response。
  • 從 knex 匯入 Knex,用於資料庫操作。

2.定義 IOrder功能:

export interface IOrderController {
createOrder(
req: Request<any, any, CreateOrderRequestParams, any>,
res: Response,
next: NextFunction
): void;
updateAmount(
req: Request<any, any, any, any>,
res: Response,
next: NextFunction
): void;
}

程式碼解說:

  1. createOrder 方法:
    • 用途:用於創建新訂單。
    • 參數:req:型別為 Request<any, any, CreateOrderRequestParams, any>,包含 CreateOrderRequestParams 介面定義的參數(支付提供者、支付方式和訂單內容)。
    • res:型別為 Response,用來回應客戶端請求。
    • next:型別為 NextFunction,用來調用下一個中介軟體。
  2. updateAmount 方法:
    • 用途:用於更新訂單中的商品數量。
    • 參數:req:型別為 Request<any, any, any, any>,沒有具體定義請求體的結構。
    • res:型別為 Response,用來回應客戶端請求。
    • next:型別為 NextFunction,用來調用下一個中介軟體。

3.定義 OrderController 類別:

export class OrderController implements IOrderController {
knexSql: Knex;
orderModel: IOrderModel;
productModel: IProductModel;
constructor({ knexSql, orderModel, productModel }: {
knexSql: Knex;
orderModel: IOrderModel;
productModel: IProductModel;
}) {
this.knexSql = knexSql;
this.orderModel = orderModel;
this.productModel = productModel
}
}

程式碼解說:

  • 繼承 IOrderController:這意味著 OrderController 必須實現 IOrderController 介面定義的方法。
  • 成員變數宣告在類別 OrderController 中,宣告了三個成員變數 knexSqlorderModelproductModel。這些變數的類型分別是 KnexIOrderModelIProductModel,用來存儲傳遞給建構子函數的值。
  • 建構函數接受 knexSql, orderModel 和 productModel 作為參數,並將它們賦值給類別的屬性。
  • 將傳入的 knexSql 資料庫連接實例賦值給 this.knexSql 屬性。
  • 將傳入的 orderModel 實例賦值給 this.orderModel 屬性,這樣可以在 OrderController 中方便地操作訂單資料。
  • 將傳入的 productModel 實例賦值給 this.productModel 屬性,確保可以在 OrderController 中操作與訂單相關的產品資料。


4.定義了一個 createOrder 的公開方法,:

public createOrder: IOrderController["createOrder"] = (req, res, _next) => {

let { paymentProvider, paymentWay, contents } = req.body
}

程式碼解說:

  • public createOrder:這表示這個方法是公開的,能夠從類別外部存取。
  • IOrderController["createOrder"]:這表示這個方法的型別必須符合 IOrderController 介面中的 createOrder 方法的定義。
  • (req, res, _next) => {}:這是一個箭頭函數,接受三個參數 req(請求物件)、res(回應物件)、_next(下一個中介軟體函數,這裡沒用到,所以用 _ 前綴表示未使用)。
  • 使用解構賦值,從請求物件 req.body 中提取 paymentProviderpaymentWaycontents 這三個屬性。
  • paymentProvider:支付提供者,例如 PayPal、信用卡等。
  • paymentWay:支付方式,例如在線支付、貨到付款等。
  • contents:訂單的內容,通常是包含商品詳細資訊的數據。


5.定義 CreateOrderRequestParams 介面:請求物件 req.body 的結構

interface CreateOrderRequestParams {
paymentProvider: PaymentProvider;
paymentWay: PaymentWay;
contents: OrderContent[];
}

程式碼解說:

  • 定義了 CreateOrderRequestParams 介面,用來描述創建訂單請求的參數結構。
  • paymentProvider:枚舉類型 PaymentProvider,指明支付提供者,如 ECPAY 或 PAYPAL。
  • paymentWay:枚舉類型 PaymentWay,指明支付方式,如 CVS 或 PAYPAL。
  • contents:一個 OrderContent 陣列,描述訂單中的每個產品項目。

6.修改IOrder功能:

createOrder(req: Request<any, any, CreateOrderRequestParams, any>, res: Response, next: NextFunction): void;








全端網頁開發專業知識分享
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
※ 路由設定: 在routes資料夾中,建立product.ts: ※ 設置產品相關的路由: 1.匯入模組: import express from 'express'; import { ControllerContext } from '@/manager/controllerM
※ 建立一個管理者的資料夾,負責建立不同的管理 — manager: ※ 在manager資料夾中,建立modelManager.ts: ※ 設定資料庫模型的管理: 匯入模組: import { IProductModel, ProductModel } from "@/model/prod
※ 認識MVC架構: ※ 認識lodash: Lodash 是一個很實用的 JavaScript 函式庫。它提供了很多預設的實用函數,可以更容易地處理數據、操作物件和字串,並控制函數的執行。目的是為了簡化重複性的代碼,減少開發時間和錯誤。 Lodash 中常用的功能: 陣列處理:_.map
※ 認識Knex.js: Knex.js是一個專門串接資料庫的抽象化層,它支援多種關聯式資料庫,包括 PostgreSQL、MySQL、MariaDB、SQLite3、Oracle 和 Amazon Redshift 等。好處是連接以上的資料庫時,可以直接使用Knex.js的語法,就會自動創建出
※ 架構設計 ※ 資料庫規劃 id:流水號,唯一代替產品名稱的辨識代碼,AUTO_INCREMENT。 name:VARCHAR(255),NOT NULL。 amount:INTEGER(整數),UNSIGNED(不能是負數)。 description:TEXT,描述產品。 pre_
※ 下載Typescript 建立 TypeScript 和 Express 的基本目錄結構和必要配置。 npm install -g typescript-express-generator 建立模板引擎: ts-express --view=ejs server 安裝node_m
※ 路由設定: 在routes資料夾中,建立product.ts: ※ 設置產品相關的路由: 1.匯入模組: import express from 'express'; import { ControllerContext } from '@/manager/controllerM
※ 建立一個管理者的資料夾,負責建立不同的管理 — manager: ※ 在manager資料夾中,建立modelManager.ts: ※ 設定資料庫模型的管理: 匯入模組: import { IProductModel, ProductModel } from "@/model/prod
※ 認識MVC架構: ※ 認識lodash: Lodash 是一個很實用的 JavaScript 函式庫。它提供了很多預設的實用函數,可以更容易地處理數據、操作物件和字串,並控制函數的執行。目的是為了簡化重複性的代碼,減少開發時間和錯誤。 Lodash 中常用的功能: 陣列處理:_.map
※ 認識Knex.js: Knex.js是一個專門串接資料庫的抽象化層,它支援多種關聯式資料庫,包括 PostgreSQL、MySQL、MariaDB、SQLite3、Oracle 和 Amazon Redshift 等。好處是連接以上的資料庫時,可以直接使用Knex.js的語法,就會自動創建出
※ 架構設計 ※ 資料庫規劃 id:流水號,唯一代替產品名稱的辨識代碼,AUTO_INCREMENT。 name:VARCHAR(255),NOT NULL。 amount:INTEGER(整數),UNSIGNED(不能是負數)。 description:TEXT,描述產品。 pre_
※ 下載Typescript 建立 TypeScript 和 Express 的基本目錄結構和必要配置。 npm install -g typescript-express-generator 建立模板引擎: ts-express --view=ejs server 安裝node_m
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
好的,很高興能為您服務!街口支付是台灣相當普及的行動支付平台,提供方便快速的付款、轉帳等服務。 街口支付的主要功能與特色: * 付款: * 掃碼付款: 在店家出示的QR code上掃描,即可完成付款。 * 出示付款碼: 店家掃描您手機上的付款碼,同樣能完成交易。 * 轉帳:
Thumbnail
什麼是代儲值? 隨著手遊市場的快速發展,遊戲內購買(in-app purchases)成為了玩家提升遊戲體驗的重要途徑之一。然而,對於某些玩家而言,直接在遊戲中充值可能會遇到支付方式限制或費用過高等問題。這時,代儲值服務應運而生。代儲值是指通過第三方平台,幫助玩家完成遊戲內的充值過程,使玩家能夠以
Thumbnail
另外一種支付方式— 終於審核通過了。現在您可以透過小額購買來支持JIN!🎶 完全以數位圖檔的方式提供,讓您可以盡情的閱讀與享受童話故事~ 收錄的故事完全沒有重複,但仍然是月費制更加划算。不過,您現在有兩種選擇,選擇適合您的方案吧!
Thumbnail
台灣Pay在韓國開通啦!只需使用新臺幣即可進行跨國交易,免收任何跨國交易手續費,並可獲得最高15%的回饋。需注意單筆交易限額、單日交易限額及單月交易限額,並留意活動回饋總額上限。
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
好的,很高興能為您服務!街口支付是台灣相當普及的行動支付平台,提供方便快速的付款、轉帳等服務。 街口支付的主要功能與特色: * 付款: * 掃碼付款: 在店家出示的QR code上掃描,即可完成付款。 * 出示付款碼: 店家掃描您手機上的付款碼,同樣能完成交易。 * 轉帳:
Thumbnail
什麼是代儲值? 隨著手遊市場的快速發展,遊戲內購買(in-app purchases)成為了玩家提升遊戲體驗的重要途徑之一。然而,對於某些玩家而言,直接在遊戲中充值可能會遇到支付方式限制或費用過高等問題。這時,代儲值服務應運而生。代儲值是指通過第三方平台,幫助玩家完成遊戲內的充值過程,使玩家能夠以
Thumbnail
另外一種支付方式— 終於審核通過了。現在您可以透過小額購買來支持JIN!🎶 完全以數位圖檔的方式提供,讓您可以盡情的閱讀與享受童話故事~ 收錄的故事完全沒有重複,但仍然是月費制更加划算。不過,您現在有兩種選擇,選擇適合您的方案吧!
Thumbnail
台灣Pay在韓國開通啦!只需使用新臺幣即可進行跨國交易,免收任何跨國交易手續費,並可獲得最高15%的回饋。需注意單筆交易限額、單日交易限額及單月交易限額,並留意活動回饋總額上限。