-
Notifications
You must be signed in to change notification settings - Fork 6
API Document
node-ecpay-aio (NEA) 是綠界全方位金流(AIO)的 Node.js SDK。NEA 是根據綠界官方 API 規格書的全新實作並且支援 TypeScript,它並非官方 SDK 的 fork 改寫版本。
因綠界主要使用者皆在台灣,故 NEA 文件皆以中文書寫。
npm install --save node-ecpay-aio
-
Merchant Class: new Merchant() / .createPayment() / .createQuery() / .createAction()
-
Payment Class: .checkout() / .placeOrder()
-
Query Class: .read()
-
Action Class: .execute()
-
Error Classes: ValidationError / PlaceOrderError / QueryError / ActionError / CheckMacValueError
-
Utilities: isValidReceivedCheckMacValue / getCurrentTaipeiTimeString
Step 1 | Step 2 | Step 3
+------------+
.createPayment() | |--> await payment.checkout()
+---------------------->| payment |
| | |--> await payment.placeOrder()
| +------------+
|
+------------+ +------------+
| | .createQuery() | |
new Merchant() --->| merchant |---------------->| query |--> await query.read()
| | | |
+------------+ +------------+
|
| +------------+
| | |
+---------------------->| action |--> await action.execute()
.createAction() | |
+------------+
-
Step 1: 建立特店(
merchant
) -
Step 2: 可以再用特店建立
- 付款方式:
payment
- 查詢:
query
- 操作:
action
- 付款方式:
-
Step 3:
- payment 可以執行結帳
- 如果是立即付款
- 一定要取得在前端重導向至綠界結帳頁面的 html:
const html = await payment.checkout()
- 一定要取得在前端重導向至綠界結帳頁面的 html:
- 如果是延遲付款
- 可以取得在前端重導向至綠界結帳頁面的 html:
const html = await payment.checkout()
- 也可直接於後端請求建立綠界訂單:
const paymentInfo = await payment.placeOrder()
- 可以取得在前端重導向至綠界結帳頁面的 html:
- 如果是立即付款
- query 可以執行讀取:
const data = await query.read()
- action 可以執行操作:
const result = await action.execute()
- payment 可以執行結帳
如何閱讀本文件
- 建議先稍微讀過官方的 API 手冊。
- 參數物件會以 必填 與 選填 兩部份區隔開。
- 因參數眾多,僅在需要之處以註解稍加說明。若對某參數不了解,請直接參考官方 API 手冊。
- 參數命名一律按官方的大寫駝峰式(Pascal Case)書寫。
- 參數 Schema 或參數間的相依條件已有防衛性驗證,違反規則即會拋錯,故 NEA 文件不會特別說明這些限制。
- 參數型別是嚴格的,字串就是字串,數字就是數字。官方的 SDK 會自動將字串轉數字,但 NEA 不會,因為這會造成型別混淆。你心裡只要記住幾乎 99% 的參數都是字串,僅有部分涉及「金額」、「次數」、「天數」的地方才會有數字出現。
- 關於可用參數及其型別、選項,TypeScript 會協助你。不過,到底要用 TS 還是 JS 來寫,由你自行決定。
- 空值與 undefined 不同。在官方手冊中提到的「空值」在 NEA 中一律是指空字串
''
而不是null
或undefined
。在 NEA,只要是undefined
的參數,皆不會編入 x-www-form-urlencoded 的鍵值對字串中。如果你想要將屬性編入 post 字串,請給予該屬性空字串''
,而非給予undefined
。綠界的請求參數並不使用null
,故請勿使用null
表示空值。
代表綠界特店的 Class,它的實例帶有工廠方法 createPayment()
、createQuery()
以及 createAction()
可以產生特店的結帳、資料查詢與信用卡作業操作。特店是指「提供綠界金流付款服務給消費者付款交易的賣家系統」,一般來講也就是你的後端系統。
import { Merchant } from 'node-ecpay-aio';
Syntax:
new Merchant(mode, config[, ecpayServiceUrls])
建立綠界特店的實例。建立時需給予組態 config
用來設定你的特店資訊。Merchant 的實例帶有工廠方法 createPayment()
、createQuery()
以及 createAction()
。
Arguments:
-
mode
(String):'Test' | 'Production'
,各表示特店要使用綠界的測試環境或生產環境 API。 -
config
(Object): 特店的組態參數如下{ // 必填 MerchantID: '2000132', HashKey: '5294y06JbISpM5x9', HashIV: 'v77hoKGq4kWxNNIS', ReturnURL: 'https://yourservice.com/foo/bar', // 選填 PlatformID: '', // 只有平台商需填此編號, 我們大部分都不是 PeriodReturnURL: 'https://...', OrderResultURL: 'https://...' , ClientBackURL: 'https://...', PaymentInfoURL: 'https://...', ClientRedirectURL: 'https://...' }
-
ecpayServiceUrls
(Object, optional): 改寫或新增綠界 API 的服務端點資料,一般不會用到此參數。為節省說明版面,此處暫省略說明。
Returns:
- (Object): merchant 實例
Errors:
- (ValidationError):
ValidationError
實例
Examples:
import { Merchant } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
MerchantID: '2000132',
HashKey: '5294y06JbISpM5x9',
HashIV: 'v77hoKGq4kWxNNIS',
ReturnURL: 'https://api.test.com/our/hook1',
PaymentInfoURL: 'https://api.test.com/our/hook2',
});
Syntax:
merchant.createPayment(PaymentClass, baseParams[, params]);
建立付款方式的工廠方法。建立時請注入要使用的 PaymentClass,並準備好每一種付款方式都要填寫的基本參數 baseParams
,以及屬於個別付款方式的專屬參數 params
。
注意
建議不要省略
params
,即使你並未使用params
中的任何屬性,請令其為空物件{}
而非undefined
,保持一致的呼叫風格。
Arguments:
-
PaymentClass
(Class): 各種付款方式的 Class,包含有-
CreditOneTimePayment
: 信用卡一次付清 -
CreditDividePayment
: 信用卡分期付款 -
CreditPeriodPayment
: 信用卡定期定額 (訂閱式收費) -
WebATMPayment
: WebATM 付款 -
ATMPayment
: ATM 付款 -
CVSPayment
: 超商代碼付款 -
BARCODEPayment
: 超商條碼付款 -
AndroidPayPayment
: Google Pay 付款。綠界 AIO 目前暫時停止此服務,目前產生AndroidPayPayment
時會拋錯
-
-
baseParams
(Object): 所有付款方式都需要填的基本參數{ // 必填 MerchantTradeNo: 'NEA12345678', // 廠商自己的訂單編號, 只接受大小寫英數字組合, min: 4, max: 20 MerchantTradeDate: '2022/04/25 18:26:12', TotalAmount: 500, TradeDesc: '交易描述', ItemName: '商品名稱', // 以下選填 Remark: '備註', NeedExtraPaidInfo: 'Y', // 'N': 不要, 'Y': 要 StoreID: '', ItemURL: 'https://...', CustomField1: '自訂欄位1', CustomField2: '自訂欄位2', CustomField3: '自訂欄位3', CustomField4: '自訂欄位4', ReturnURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook ClientBackURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的返回網址 OrderResultURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要顯示個別的付款結果網址 }
-
params
(Object): 根據不同的 PaymentClass 付款方式,各自需要的獨特參數。分述於下方各種付款方式範例。
Returns:
- (Object): payment 實例
Errors:
- (ValidationError):
ValidationError
實例
Examples:
- 付款模式: 立即付款(須導向綠界結帳頁)
- 付款類別:
CreditOneTimePayment
import { Merchant, CreditOneTimePayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
MerchantTradeNo: 'NEA12345678',
MerchantTradeDate: '2021/04/17 10:55:26',
TotalAmount: 1000,
TradeDesc: '交易描述',
ItemName: '商品名稱',
// ReturnURL: undefined, // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
// ClientBackURL: undefined, // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的轉導網址
// OrderResultURL: undefined, // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的轉導網址
};
const params: CreditOneTimePaymentParams = {
// 皆為選填
BindingCard: 1, // 記憶信用卡: 1 (記) | 0 (不記)
MerchantMemberID: '2000132u001', // 記憶卡片需加註識別碼: MerchantId+廠商會員編號
Language: 'ENG', // 語系: undefined(繁中) | 'ENG' | 'KOR' | 'JPN' | 'CHI'
Redeem: 'Y', // 紅利折抵: undefined(不用) | 'Y' (使用)
UnionPay: 2, // [需申請] 銀聯卡: 0 (可用, default) | 1 (導至銀聯網) | 2 (不可用)
};
const payment = merchant.createPayment(
CreditOneTimePayment,
baseParams,
params
);
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
- 付款模式: 立即付款(須導向綠界結帳頁)
- 付款類別:
CreditDividePayment
import { Merchant, CreditDividePayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const extraParams: CreditDividePaymentParams = {
// 必填
CreditInstallment: '3', // 分期數: '3' | '6' | '12' | '18' | '24' | '30N'(圓夢彈性分期)
// 選填
BindingCard: 0,
MerchantMemberID: undefined, // 寫 undefined 只是表示有此參數可設定, 實際上不賦值就不用寫此屬性
Language: undefined, // 同上
Redeem: undefined, // 同上
UnionPay: undefined, // 同上
};
const payment = merchant.createPayment(CreditDividePayment, baseParams, params);
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
- 付款模式: 立即付款(須導向綠界結帳頁)
- 付款類別:
CreditPeriodPayment
import { Merchant, CreditPeriodPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: CreditPeriodPaymentParams = {
// 必填
PeriodAmount: 500, // 週期授權金額, 須與 baseParams.TotalAmount 相等, 否則拋錯
PeriodType: 'M', // 'D'(日) | 'M'(月) | 'Y'(年)
Frequency: 1, // 多久執行一次, min: 1, max: 365(天) | 12(月) | 1(年)
ExecTimes: 10, // 執行次數, min: 1, max: 999(天) | 99(月) | 9(年)
// 選填
BindingCard: 0,
MerchantMemberID: undefined,
Language: undefined,
Redeem: undefined,
UnionPay: 2,
PeriodReturnURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
};
const payment = merchant.createPayment(CreditPeriodPayment, baseParams, params);
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
- 付款模式: 立即付款(須導向綠界結帳頁)
- 付款類別:
WebATMPayment
import { Merchant, WebATMPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: WebATMPaymentParams = {
/* 無參數, 請保持空物件*/
};
const payment = merchant.createPayment(WebATMPayment, baseParams, params);
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
- 付款模式: 延遲付款(可選擇是否導向綠界結帳頁)
- 付款類別:
ATMPayment
import { Merchant, ATMPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: ATMPaymentParams = {
// 皆選填
ExpireDate: 7,
PaymentInfoURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
ClientRedirectURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
};
const payment = merchant.createPayment(ATMPayment, baseParams, params);
// pick one
// (1) 取得前端瀏覽器重新導向的 Post Form
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
// 或 (2) 於後端直接建立訂單, paymentInfo 為取號結果
const paymentInfo = await payment.placeOrder(/* 可選填發票 */);
- 付款模式: 延遲付款(可選擇是否導向綠界結帳頁)
- 付款類別:
CVSPayment
import { Merchant, CVSPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: CVSPaymentParams = {
// 皆選填
StoreExpireDate: 7,
Desc_1: 'POS 機顯示條目 1',
Desc_2: 'POS 機顯示條目 2',
Desc_3: 'POS 機顯示條目 3',
Desc_4: 'POS 機顯示條目 4',
PaymentInfoURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
ClientRedirectURL: 'https://...', // 若在 merchant 設定過, 此處不需再設定, 除非你針對此單要用個別的 hook
};
const payment = merchant.createPayment(CVSPayment, baseParams, params);
// pick one
// (1) 取得前端瀏覽器重新導向的 Post Form
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
// 或 (2) 於後端直接建立訂單, paymentInfo 為取號結果
const paymentInfo = await payment.placeOrder(/* 可選填發票 */);
- 付款模式: 延遲付款(可選擇是否導向綠界結帳頁)
- 付款類別:
BARCODEPayment
import { Merchant, BARCODEPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const extraParams: BARCODEPaymentParams = {
// 皆為可選
StoreExpireDate: 7,
PaymentInfoURL: 'https://...', // 不必特別設定, 因未設定會自動吃 merchant config 的值
ClientRedirectURL: 'https://...', // 不必特別設定, 因未設定會自動吃 merchant config 的值
Desc_1: 'POS 機顯示條目 1',
Desc_2: 'POS 機顯示條目 2',
Desc_3: 'POS 機顯示條目 3',
Desc_4: 'POS 機顯示條目 4',
};
const payment = merchant.createPayment(BARCODEPayment, baseParams, params);
// pick one
// (1) 取得前端瀏覽器重新導向的 Post Form
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
// 或 (2) 於後端直接建立訂單, paymentInfo 為取號結果
const paymentInfo = await payment.placeOrder(/* 可選填發票 */);
- 付款模式: 立即付款(AIO 目前已停止本服務)
- 付款類別:
AndroidPayPayment
import { Merchant, AndroidPayPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: AndroidPayPaymentParams = {
/* 綠界當前不提供此服務, 無參數, 請保持空物件 */
};
const payment = merchant.createPayment(AndroidPayPayment, baseParams, params);
const htmlRedirectPostForm = await payment.checkout(/* 可選填發票 */);
- 付款模式: 立即付款/延遲付款(須導向綠界結帳頁;不支援
placeOrder()
) - 付款類別:
ALLPayment
import { Merchant, ALLPayment } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const baseParams: BasePaymentParams = {
/* 略 */
};
const params: ALLPaymentParams = {
// 選填
IgnorePayment: ['WebATM', 'ATM'],
// 陣列可填 'Credit', 'WebATM', 'ATM', 'CVS', 'BARCODE', 'AndroidPay'
// 表示不提供這些付款方式給消費者選擇
// 其餘參數: 根據可用的付款方式, 將所有 params 結合起來在此設定
// 個別設定請參考前述 1~8 之設定
BindingCard: 0,
MerchantMemberID: undefined,
Language: undefined,
Redeem: undefined,
UnionPay: 2,
// ... 略
};
const payment = merchant.createPayment(ALLPayment, baseParams, params);
const htmlRedirectPostForm = await payment.checkout();
Syntax:
merchant.createQuery(QueryClass, params);
建立交易資料查詢的工廠方法。建立時請注入要使用的 QueryClass,並準備好每一種查詢要填寫的參數 params
。建立的 QueryClass 實例具有 .read()
的非同步方法可以向綠界服務發起查詢請求。查詢結果的響應格式請見 Query Class: 5.1 .read() API 說明。Query 是冪等操作。
注意
建議不要省略
params
,即使你並未使用params
中的任何屬性,請令其為空物件{}
而非undefined
。
Arguments:
-
QueryClass
(Class): 各種查詢的 Class,包含有-
TradeInfoQuery
: 訂單資料查詢 -
PaymentInfoQuery
: ATM/CVS/BARCODE 取號結果查詢 -
CreditCardPeriodInfoQuery
: 信用卡定期定額訂單查詢 -
TradeV2Query
: 查詢信用卡單筆明細紀錄 -
TradeNoAioQuery
: 下載特店對帳媒體檔 -
FundingReconDetail
: 下載信用卡撥款對帳資料檔
-
-
params
(Object): 根據不同的 QueryClass 查詢方式,各自所需的獨特參數。分述於下方各種查詢範例。
Returns:
- (Object): Query 實例
Errors:
- (ValidationError):
ValidationError
實例
Examples:
- 查詢類別:
TradeInfoQuery
import { Merchant, TradeInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read();
- 查詢類別:
PaymentInfoQuery
import { Merchant, PaymentInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(PaymentInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read();
- 查詢類別:
CreditCardPeriodInfoQuery
import { Merchant, CreditCardPeriodInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(CreditCardPeriodInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read();
- 查詢類別:
TradeV2Query
import { Merchant, TradeV2Query } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeV2Query, {
CreditRefundId: 10123456, // baseParams.NeedExtraPaidInfo = 'Y' 時取得詳情中的 gwsr 值即是此 Id
CreditAmount: 500,
CreditCheckCode: 59997889, // 商家檢查碼, 後台 > 信用卡收單 > 信用卡授權資訊可查到
});
const data = await query.read();
- 查詢類別:
TradeNoAioQuery
import { Merchant, TradeNoAioQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeNoAioQuery, {
// 必填
DateType: '2', // '2'(付款日) | '4'(撥款日) | '6'(訂單日)
BeginDate: '2022-04-25',
EndDate: '2022-04-26',
MediaFormated: '1', // '0'(舊格式) | '1'(新格式)
// 選填
PaymentType: '01', // '01'(信用卡) | '02'(WebATM) | '03'(ATM) | '04'(CVS) |
// '05'(BARCODE) | '10'(全家立即儲) | '11'(圓夢彈性分期);
PlatformStatus: undefined, // undefined(全部) | '1'(一般) | '2'(平台)
PaymentStatus: '0', // undefined(全部) | '0'(未付款) | '1'(已付款) | '2'(訂單失敗)
AllocateStatus: undefined, // undefined(全部) | '0'(未撥款) | '1'(已撥款)
CharSet: '1', // undefeind(Server預設) | '1'(Big5) | '2'(utf8);
});
const data = await query.read(); // csv檔
- Response data: 純文字 (.csv 檔)
- 查詢類別:
FundingReconDetail
import { Merchant, FundingReconDetail } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(FundingReconDetail, {
// 必填
PayDateType: 'fund', // 'fund'(依結算日) | 'close'(依關帳日) | 'enter'(依撥款日)
StartDate: '2022-04-25',
EndDate: '2022-04-26',
MediaFormated: '1', // '0'(舊格式) | '1'(新格式)
// 選填
CharSet: '1', // undefeind(Server預設) | '1'(Big5) | '2'(utf8);
});
const data = await query.read(); // csv檔
- Response data: 純文字 (.csv 檔)
Syntax:
merchant.createAction(ActionClass, params);
建立操作的工廠方法。建立時請注入要使用的 ActionClass,並準備好每一種操作要填寫的參數 params
。建立的 ActionClass 實例具有 .execute()
的非同步方法可以向綠界服務發起遠端操作請求。操作結果的響應格式請見 Action Class: 6.1 .execute() API 說明。Action 是非冪等操作。
注意
建議不要省略
params
,即使你並未使用params
中的任何屬性,請令其為空物件{}
而非undefined
。
Arguments:
-
ActionClass
(Class): 各種操作的 Class,包含有-
DoAction
: 信用卡請退款作業 -
CreditCardPeriodAction
: 信用卡定期定額訂單作業
-
-
params
(Object): 根據不同的 Action Class 操作方式,各自所需的獨特參數。分述於下方各種操作範例。
Returns:
- (Object): action 實例
Errors:
- (ValidationError):
ValidationError
實例
Examples:
- 操作類別:
DoAction
const action = merchant.createAction(DoAction, {
// 皆為必填
MerchantTradeNo: 'NEA12345678',
TradeNo: '8811223388121'.
Action: 'C' , // 'C'(關帳) | 'R'(退刷) | 'E'(取消) | 'N'(放棄)
TotalAmount: 500
});
const result = await action.execute();
- 響應資料格式請見 6.1 excute() 說明。
- 操作類別:
CreditCardPeriodAction
const action = merchant.createAction(CreditCardPeriodAction, {
// 皆為必填
MerchantTradeNo: 'NEA12345678',
Action: 'ReAuth', // 'ReAuth' | 'Cancel';
});
const result = await action.execute();
- 響應資料格式請見 6.1 excute() 說明。
Payment Classes 分類如下:
-
立即付款類
-
CreditOneTimePayment
: 信用卡一次付清 -
CreditDividePayment
: 信用卡分期付款 -
CreditPeriodPayment
: 信用卡定期定額 (訂閱式收費) -
AndroidPayPaymen
: Google Pay 付款。綠界目前暫時停止此服務,目前產生 AndroidPayPayment 時會自動 throw Error。
-
-
延遲付款類
-
WebATMPayment
: WebATM 付款 -
ATMPayment
: ATM 付款 -
CVSPayment
: 超商代碼付款 -
BARCODEPayment
: 超商條碼付款
-
Syntax:
payment.checkout([invoice]);
所有的 Payment Classes 都有 .checkout()
的結帳方法。
如果需要開立電子發票,請於結帳時帶入發票參數 chekcout(invoice)
。如不開立發票,直接執行checkout()
即可。關於帶入的發票請見 8. 發票格式 說明。
Arguments:
-
invoice
(Object, optional): 發票參數。結帳時填入可一併開立電子發票。
Returns:
- (String): 傳給前端重導向至綠界結帳頁的 Post Form
Errors:
- (ValidationError):
ValidationError
實例
Examples:
const htmlRedirectPostForm = await payment.checkout();
-
Result (htmlRedirectPostForm)
<form id="_form_aio_checkout" action="https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5" method="post" > <input type="hidden" name="CheckMacValue" id="CheckMacValue" value="2C6E582088B63CE828D27CE7E89FE0BA840F2599F10002A6AC0213DFD147C116" />...略...<input type="hidden" name="TradeDesc" id="TradeDesc" value="node-ecpay-aio testing order for CreditOneTimePayment" /> <script type="text/javascript"> document.getElementById('_form_aio_checkout').submit(); </script> </form>
const invoice: InvoiceParams = {
RelateNumber: 'foo-rl-no',
TaxType: '1',
Donation: '0',
Print: '0',
InvoiceItemName: 'item1|item2',
InvoiceItemCount: '2|5',
InvoiceItemWord: '台|張',
InvoiceItemPrice: '100|50',
InvoiceRemark: '測試發票備註',
CustomerPhone: '0911111111',
};
const htmlRedirectPostForm = await payment.checkout(invoice);
-
Result (htmlRedirectPostForm)
<form id="_form_aio_checkout" action="https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5" method="post" > <input type="hidden" name="CarruerType" id="CarruerType" value="" /><input type="hidden" name="CheckMacValue" id="CheckMacValue" value="3185EDD19B600CA2780AD3DE387DB09434A84AE0BE37B64EB36C428D3BA40264" />...略...<input type="hidden" name="TotalAmount" id="TotalAmount" value="999" /><input type="hidden" name="TradeDesc" id="TradeDesc" value="node-ecpay-aio testing order for CreditOneTimePayment" /> <script type="text/javascript"> document.getElementById('_form_aio_checkout').submit(); </script> </form>
Syntax:
payment.placeOrder([invoice]);
只有延遲付款的 Payment Classes 才有 .placeOrder()
方法。 如果需要開立電子發票,請於結帳時帶入發票參數placeOrder(invoice)
。如不開立發票,直接執行placeOrder()
即可。
Arguments:
-
invoice
(Object, optional): 發票參數。結帳時填入可一併開立電子發票。
Returns:
- (Object): 延遲付款訂單的取號結果。
- ATM
{ CheckMacValue: 'ABCD...', MerchantID: '2000132', StoreID: '', MerchantTradeNo: 'NEA12345678', CustomField1: '', CustomField2: '', CustomField3: 'N22042600020', CustomField4: 'ATM', TradeNo: '2204261421418645', TradeDate: '2022/04/26 14:21:51', TradeAmt: 409, PaymentType: 'ATM_LAND', ExpireDate: '2022/04/29', BankCode: '005', vAccount: '5219111913209840', RtnCode: 2, RtnMsg: 'Get VirtualAccount Succeeded', }
- 超商代碼 (CVS)
{ CheckMacValue: 'ABCD...', MerchantID: '2000132', StoreID: '', MerchantTradeNo: '7c80cdef716c4a2998d', CustomField1: '', CustomField2: '', CustomField3: '', CustomField4: '', TradeNo: '2204261439048696', TradeDate: '2022/04/26 14:39:30', TradeAmt: 200, PaymentType: 'CVS_CVS', ExpireDate: '2022/05/03 14:39:30', PaymentNo: 'LLL22116735498', PaymentURL: 'https://payment-stage.ecpay.com.tw/PaymentRule/CVSBarCode?PaymentNo=LLL22116735498', RtnCode: 10100073, RtnMsg: 'Get CVS Code Succeeded.', }
- 超商條碼 (BARCODE)
{ CheckMacValue: 'ABCD...', MerchantID: '2000132', StoreID: '', MerchantTradeNo: 'CK20220426401292', CustomField1: '', CustomField2: '', CustomField3: '', CustomField4: '', TradeNo: '2204261401048597', TradeDate: '2022/04/26 14:02:17', TradeAmt: 1500, PaymentType: 'BARCODE_BARCODE', ExpireDate: '2022/05/03 14:39:30', Barcode1: '1105036EA', Barcode2: '3453011539919569', Barcode3: '042677000001500', RtnCode: 10100073, RtnMsg: 'Get CVS Code Succeeded.', }
- ATM
Errors:
- (PlaceOrderError):
PlaceOrderError
實例 - (CheckMacValueError):
CheckMacValueError
實例
Examples:
const info = await payment.placeOrder();
const invoice: InvoiceParams = {
RelateNumber: 'foo-rl-no',
TaxType: '1',
Donation: '0',
Print: '0',
InvoiceItemName: 'item1|item2',
InvoiceItemCount: '2|5',
InvoiceItemWord: '台|張',
InvoiceItemPrice: '100|50',
InvoiceRemark: '測試發票備註',
CustomerPhone: '0911111111',
};
const info = await payment.placeOrder(invoice);
交易資料查詢的 Query Classes,包含有:
-
TradeInfoQuery
: 訂單資料查詢 -
PaymentInfoQuery
: ATM/CVS/BARCODE 取號結果查詢 -
CreditCardPeriodInfoQuery
: 信用卡定期定額訂單查詢 -
TradeV2Query
: 查詢信用卡單筆明細紀錄 -
TradeNoAioQuery
: 下載特店對帳媒體檔 -
FundingReconDetail
: 下載信用卡撥款對帳資料檔
每個 QueryClass 實例具有 .read()
的非同步方法可以向綠界服務發起查詢請求,響應格式如下所列。
Syntax:
query.read()
所有的 Query Classes 都有 .read()
的非同步讀取查詢資料方法。
Arguments:
- none
Returns:
- (Promise): promise
Errors:
- (QueryError):
QueryError
實例 - (CheckMacValueError):
CheckMacValueError
實例
Examples:
import { Merchant, TradeInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read(); // 響應格式列如下方
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: 'NEA12345678',
ItemName: '手機/平板 鋁合金桌面支架 | 人體工 學追劇必備#',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261428508660',
TradeDate: '2022/04/26 14:28:50',
TradeAmt: 1440,
TradeStatus: '1',
HandlingCharge: 29,
PaymentDate: '2022/04/26 14:29:15',
PaymentType: 'Credit_CreditCard',
PaymentTypeChargeFee: 29,
// 以下欄位只有當結帳時 baseParams.NeedExtraPaidInfo 設 'Y' 才有
// 故不一定會在響應資料中出現
// 以下欄位和信用卡交易方式有關
process_date: '2022/04/27 17:19:44',
amount: 1440,
auth_code: '777777',
gwsr: 11718189,
eci: 0,
card4no: '2222',
card6no: '431195',
// 以下欄位和此交易方式無關
ATMAccBank: '',
ATMAccNo: '',
WebATMBankName: '',
WebATMAccBank: '',
WebATMAccNo: '',
PayFrom: '',
PaymentNo: '',
red_dan: '',
red_de_amt: '',
red_ok_amt: '',
red_yet: '',
staed: '',
stage: '',
stast: '',
// 以下官方已棄用
AlipayID: '',
AlipayTradeNo: '',
TenpayTradeNo: '',
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: '20211026001969730',
ItemName: '鋁合金桌面支架',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2110261713558708',
TradeDate: '2021/10/26 17:13:55',
TradeAmt: 200,
TradeStatus: '1',
HandlingCharge: 5,
PaymentDate: '2021/10/26 17:14:27',
PaymentType: 'Credit_CreditCard',
PaymentTypeChargeFee: 5,
PeriodType: 'D',
Frequency: 91,
ExecTimes: 999,
TotalSuccessTimes: 3,
PeriodAmount: 200,
TotalSuccessAmount: 600,
// 以下欄位和信用卡交易方式有關
process_date: '2021/10/26 17:14:27',
amount: 200,
auth_code: '777777',
gwsr: 11718189,
card4no: '2222',
card6no: '431195',
eci: '', // 當非數字時,保持空值(空字串)
// 其餘欄位和此交易方式無關, 也不一定會出現
// 所有欄位請參考上方完整的 response data 格式
// ...略
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: '20220426133333',
ItemName: '湊町十六-打go嚴選-【黑水】雙鬥茶 200 元 x 2#運費 137 元 x 1',
CustomField1: '商家統一編號:83269087',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261333378539',
TradeDate: '2022/04/26 13:33:37',
TradeAmt: '537',
TradeStatus: '1',
HandlingCharge: '10',
PaymentDate: '2022/04/26 13:33:45',
PaymentType: 'WebATM_TAISHIN',
PaymentTypeChargeFee: '10',
WebATMBankName: '',
WebATMAccBank: '812',
WebATMAccNo: '15646',
// 其餘欄位和此交易方式無關, 也不一定會出現
// 所有欄位請參考上方完整的 response data 格式
// ...略
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: 'N22042600020513',
ItemName:
'日本金鳥-吊掛式蚊香盤一般尺寸 173 元 X1#雙龍牌 日式兒童前開式雨衣-XS/S/M/L 136 元 X1',
CustomField1: '',
CustomField2: '',
CustomField3: 'N22042600020',
CustomField4: 'ATM',
TradeNo: '2204261421418645',
TradeDate: '2022/04/26 14:21:41',
TradeAmt: 409,
TradeStatus: '0',
HandlingCharge: '10',
PaymentDate: '',
PaymentType: 'ATM_LAND',
PaymentTypeChargeFee: 10,
ATMAccBank: '',
ATMAccNo: '',
// 其餘欄位和此交易方式無關, 也不一定會出現
// 所有欄位請參考上方完整的 response data 格式
// ...略
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: '2204220310222',
ItemName: '顥陽蘭坊 5000 TWD x 1',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261439048696',
TradeDate: '2022/04/26 14:39:04',
TradeAmt: 200,
TradeStatus: '1',
HandlingCharge: '0',
PaymentNo: 'LLL22112732600',
PaymentDate: '2022/04/22 14:11:30',
PaymentType: 'CVS_CVS',
PayFrom: 'ibon',
PaymentTypeChargeFee: 0,
// 其餘欄位和此交易方式無關, 也不一定會出現
// 所有欄位請參考上方完整的 response data 格式
// ...略
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: '2204220310222',
ItemName: '顥陽蘭坊 5000 TWD x 1',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261439048696',
TradeDate: '2022/04/26 14:39:04',
TradeAmt: 200,
TradeStatus: '1',
HandlingCharge: 0,
PaymentNo: 'LLL22112732600',
PaymentDate: '2022/04/22 14:11:30',
PaymentType: 'BARCODE_BARCODE',
PayFrom: 'family',
PaymentTypeChargeFee: 0,
// 其餘欄位和此交易方式無關, 也不一定會出現
// 所有欄位請參考上方完整的 response data 格式
// ...略
}
import { Merchant, PaymentInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(PaymentInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read();
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: 'NEA12345678',
CustomField1: '',
CustomField2: '',
CustomField3: 'N22042600020',
CustomField4: 'ATM',
TradeNo: '2204261421418645',
TradeDate: '2022/04/26 14:21:51',
TradeAmt: 409,
PaymentType: 'ATM_LAND',
ExpireDate: '2022/04/29',
BankCode: '005',
vAccount: '5219111913209840',
RtnCode: 2,
RtnMsg: 'Get VirtualAccount Succeeded',
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: '7c80cdef716c4a2998d',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261439048696',
TradeDate: '2022/04/26 14:39:30',
TradeAmt: 200,
PaymentType: 'CVS_CVS',
ExpireDate: '2022/05/03 14:39:30',
PaymentNo: 'LLL22116735498',
PaymentURL:
'https://payment-stage.ecpay.com.tw/PaymentRule/CVSBarCode?PaymentNo=LLL22116735498',
RtnCode: 10100073,
RtnMsg: 'Get CVS Code Succeeded.',
}
{
CheckMacValue: 'ABCD...',
MerchantID: '2000132',
StoreID: '',
MerchantTradeNo: 'CK20220426401292',
CustomField1: '',
CustomField2: '',
CustomField3: '',
CustomField4: '',
TradeNo: '2204261401048597',
TradeDate: '2022/04/26 14:02:17',
TradeAmt: 1500,
PaymentType: 'BARCODE_BARCODE',
ExpireDate: '2022/05/03 14:39:30',
Barcode1: '1105036EA',
Barcode2: '3453011539919569',
Barcode3: '042677000001500',
RtnCode: 10100073,
RtnMsg: 'Get CVS Code Succeeded.',
}
import { Merchant, CreditCardPeriodInfoQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(CreditCardPeriodInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const data = await query.read();
{
MerchantID: '2000132',
MerchantTradeNo: 'a2394da5fa5c4ef6b0b',
TradeNo: '2204260959138173',
PeriodType: 'M',
Frequency: 1,
ExecTimes: 12,
TotalSuccessTimes: 1,
PeriodAmount: 100,
TotalSuccessAmount: 100,
RtnCode: 1,
ExecStatus: '1',
ExecLog: [
{
RtnCode: 1,
RtnMsg: '成功.',
TradeNo: '2204260959138173',
amount: 100,
auth_code: '777777',
gwsr: 11955800,
process_date: '2022/04/26 10:00:22',
},
],
process_date: '2022/04/26 10:00:22',
amount: 100,
auth_code: '777777',
gwsr: 11955800,
card4no: '4444',
card6no: '431195',
}
import { Merchant, TradeV2Query } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeV2Query, {
CreditRefundId: 10123456, // baseParams.NeedExtraPaidInfo = 'Y' 時取得詳情中的 gwsr 值即是此 Id
CreditAmount: 500,
CreditCheckCode: 59997889, // 商家檢查碼, 後台 > 信用卡收單 > 信用卡授權資訊可查到
});
const data = await query.read();
{
RtnMsg: "",
RtnValue: {
TradeID: '0015625112',
amount: 100,
clsamt: 100,
authtime: "2016/5/12 下午 07:09:17",
status: "已關帳"
close_data: [
{
status: "已關帳",
sno: "2782343",
amount: 100,
datetime: "2016/5/12 下午 08:00:00"
}
]
},
}
import { Merchant, TradeNoAioQuery } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(TradeNoAioQuery, {
// 必填
DateType: '2', // '2'(付款日) | '4'(撥款日) | '6'(訂單日)
BeginDate: '2022-04-25',
EndDate: '2022-04-26',
MediaFormated: '1', // '0'(舊格式) | '1'(新格式)
// 選填
PaymentType: '01', // '01'(信用卡) | '02'(WebATM) | '03'(ATM) | '04'(CVS) | '05'(BARCODE) | '10'(全家立即儲) | '11'(圓夢彈性分期);
PlatformStatus: undefined, // undefined(全部) | '1'(一般) | '2'(平台)
PaymentStatus: '0', // undefined(全部) | '0'(未付款) | '1'(已付款) | '2'(訂單失敗)
AllocateStatus: undefined, // undefined(全部) | '0'(未撥款) | '1'(已撥款)
CharSet: '1', // undefeind(Server預設) | '1'(Big5) | '2'(utf8);
});
const data = await query.read(); // csv檔
- 純文字 (.csv 檔)
- 錯誤訊息綠界置於 cvs 檔案內
import { Merchant, FundingReconDetail } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const query = merchant.createQuery(FundingReconDetail, {
// 必填
PayDateType: 'fund', // 'fund'(依結算日) | 'close'(依關帳日) | 'enter'(依撥款日)
StartDate: '2022-04-25',
EndDate: '2022-04-26',
MediaFormated: '1', // '0'(舊格式) | '1'(新格式)
// 選填
CharSet: '1', // undefeind(Server預設) | '1'(Big5) | '2'(utf8);
});
const data = await query.read(); // csv檔
- 純文字 (.csv 檔)
- 錯誤訊息綠界置於 cvs 檔案內
Syntax:
action.execute();
所有的 Action Classes 都有 .execute()
的執行操作方法。
Arguments:
- none
Returns:
- (Promise): promise
Errors:
- (ActionError):
ActionError
實例 - (CheckMacValueError):
CheckMacValueError
實例
Examples:
import { Merchant, DoAction } from 'node-ecpay-aio';
const merchant = new Merchant('Test', {
/* 略 */
});
const action = merchant.createAction(DoAction, {
// 皆為必填
MerchantTradeNo: 'NEA12345678',
TradeNo: '8811223388121'.
Action: 'C' , // 'C'(關帳) | 'R'(退刷) | 'E'(取消) | 'N'(放棄)
TotalAmount: 500
});
try {
const reuslt = await action.execute(); // 響應格式列如下方
} catch (err) {
console.log(err);
}
{
MerchantID: '2000132',
MerchantTradeNo: '20211026001969730',
TradeNo: '20120315174058256423',
RtnCode: 1,
RtnMsg: '關帳成功',
}
try {
const data = query.read();
} catch (err) {
console.log(err.name);
console.log(err.code);
console.log(err.message);
console.log(err.response);
}
{
name: 'ECPayReturnedActionError',
code: 10200047, // TBD
message: 'Cant not find the trade data.',
response: '/{ ... /}' // 原始響應的 json string
}
{
CheckMacValue: '205B4135AAB1F78AAD407838E344A291C0CCD67BB3188A58992B07F27BE61006',
MerchantID: '2000132',
MerchantTradeNo: '20211026001969730',
RtnCode: 1,
RtnMsg: '停用成功',
}
try {
const data = query.read();
} catch (err) {
console.log(err.name);
console.log(err.code);
console.log(err.message);
console.log(err.response);
}
{
name: 'ECPayReturnedQueryError',
code: 10200047,
message: 'Cant not find the trade data.',
response: '/{ ... /}' // 原始響應的 json string
}
{
name: 'CheckMacValueError',
message: 'Invalid CheckMacValue. MerchantTradeNo: NEA87654321.',
response: '/{ ... /}' // 原始響應的 json string
}
-
無法查詢「信用卡」、「ATM」立即付款的資訊(
PaymentInfoQuery
只適用查詢延遲付款訂單)
try {
const data = query.read();
} catch (err) {
console.log(err.name);
console.log(err.code);
console.log(err.message);
console.log(err.response);
}
{
name: 'ECPayReturnedQueryError',
code: 10200047,
message: 'Cant not find the trade data.',
response: '/{ ... /}' // 原始響應的 json string
}
{
name: 'CheckMacValueError',
message: 'Invalid CheckMacValue. MerchantTradeNo: NEA87654321.',
response: '/{ ... /}' // 原始響應的 json string
}
- 無法查詢信用卡「一次付清」、「分期」付款資訊
try {
const data = query.read();
} catch (err) {
console.log(err.name);
console.log(err.code);
console.log(err.message);
console.log(err.response);
}
{
name: 'ECPayReturnedQueryError',
code: 10200047,
message: 'Cant not find the trade data.',
response: '/{ ... /}' // 原始響應的 json string
}
try {
const data = query.read();
} catch (err) {
console.log(err.name);
console.log(err.code);
console.log(err.message);
console.log(err.response);
}
{
name: 'ECPayReturnedQueryError',
code: 10200047,
message: 'Cant not find the trade data.',
response: '/{ ... /}' // 原始響應的 json string
}
Syntax:
isValidReceivedCheckMacValue(data, hashKey, hashIV);
用於檢驗 data
物件中的 CheckMacValue
值是否正確。如果 data
中並未帶有 CheckMacValue
欄位,函數執行時將會拋出錯誤。NEA 提供的查詢 API 會自動檢驗響應的校驗碼是否正確,故此函數的主要用途給開發者在實作 ReturnURL
, PeriodReturnURL
, PaymentInfoURL
等 webhooks 時檢驗收到的資料時使用。
Arguments:
-
data
(Object): 帶有CheckMacValue
欄位的資料物件。 -
hashKey
(String): 綠界配發給特店的檢驗碼。 -
hashIV
(String): 綠界配發給特店的檢驗碼。
Returns:
- (Boolean):
true
檢驗符合,false
檢驗不符
Errors:
- (CheckMacValueError):
CheckMacValueError
實例
Examples:
import { isValidReceivedCheckMacValue } from 'node-ecpay-aio';
const reponseDataToCheck = {
CheckMacValue: 'ABCD...',
// ... 其它欄位
};
try {
const isValid = isValidReceivedCheckMacValue(reponseDataToCheck);
console.log(isValid); // true
} catch (err) {
console.log(err);
// { name: 'CheckMacValueError', message: 'No CheckMacValue field within data.' }
}
Syntax:
getCurrentTaipeiTimeString([config]);
由於生產環境可能部署在世界任意時區的伺服器,。
Arguments:
-
config
(Object, optional): 設定物件。
-
timestamp
(Number, optional): UNIX timestamp milliseconds -
format
(String, optional):'Datetime'
|'Date'
|'Serial'
-
'Datetime'
: 函數將傳出'2022/05/17 10:55:26'
日期時分秒格式之字串 -
'Date'
: 函數將傳出'2022/05/17'
日期格式之字串 -
'Serial'
: 函數將傳出'20220517105526763'
時間流水號(至毫秒)格式之字串
-
{
}
Returns:
- (Boolean):
true
檢驗符合,false
檢驗不符
Errors:
- (CheckMacValueError):
CheckMacValueError
實例
Examples:
import { isValidReceivedCheckMacValue } from 'node-ecpay-aio';
const reponseDataToCheck = {
CheckMacValue: 'ABCD...',
// ... 其它欄位
};
try {
const isValid = isValidReceivedCheckMacValue(reponseDataToCheck);
console.log(isValid); // true
} catch (err) {
console.log(err);
// { name: 'CheckMacValueError', message: 'No CheckMacValue field within data.' }
}
-
關於發票格式詳細說明與限制,請參閱綠界官方 AIO 技術文件說明,下方盡可能摘要重點。
-
NEA 會驗證發票參數格式與相依條件,若設定有誤則會立即拋錯。
-
對大部分商家來講,開立發票多是應稅 (
TaxType: '1'
)且一般稅額 (InvType: '07'
)。如果你的發票是混合型或有特殊行業別的稅額,請另外申請電子發票服務,AIO 提供的發票功能只能滿足一般商業交易場景。const invoice = { // 必填 TaxType: '1', // '1': 應稅, '2': 零税, '3': 免稅, '9': 混合 Print: '1', // '1': 列印, '0': 不印, 有統編時只能選列印, 捐贈時只能選不印, Donation: '0', // '0': 不捐贈, '1': 捐贈, 當有統編時不能填捐贈 RelateNumber: 'suggest-unique-id', // 長度最大30字元 InvoiceItemName: '品名1|品名2', // 多商品以 | 隔開, 中間無空格 InvoiceItemCount: '2|5', // 商品數量, 多商品以 | 隔開 InvoiceItemWord: '台|張', // 單位 InvoiceItemPrice: '100|50', // 單價(預設含稅) // 必填, 二擇一, 發票開立與中獎通知用 CustomerPhone: '0912345678', // 聯絡電話, 必需要為手機號碼 CustomerEmail: 'nea@example.com', // 電子信箱 // 選填 InvoiceItemTaxType: '1|1', // '1': 應稅, '2': 零税, '3': 免稅 InvoiceRemark: '備註欄文字', // 選填: 載具與捐贈 LoveCode: '123456', // 受贈單位碼, 當選擇捐贈時, 此欄必填 ClearanceMark: '1', // '1': 非經海關, '2': 經海關, TaxType若為'2', 此欄必填 CarruerType: '', // '': 無載具, '1': 特店載具, '2': 自然人憑證, '3': 手機條碼; // 若有設統編或發票要列印時, CarruerType 只能設定為無載具 CarruerNum: '', // 無載具: '', 特店載具: '統編+RelateNumber(此欄由綠界設定)' // 自然人憑證: 'AB12345...', 手機條碼: '/Yabc123' // 選填: 統編與客戶資料 CustomerID: 'NEA_U_0000000001', // 自訂的客戶編號, 最長20字元 CustomerIdentifier: '12345678', // 統編 CustomerName: 'NEA神秘開發公司', // 客戶名稱, 若設定要印發票證明則必填 CustomerAddr: '宇宙市太陽區地球路1號', // 客戶地址, 若設定要印發票證明則必填 // 選填: 其它 DelayDay: 0, // 預設0為立即開立, 最大可設到15天後自動開立 InvType: '07', // AIO 固定為 '07': 一般稅額, 若有其他稅額需求須申請電子發票服務 };
Examples:
-
買受人是一般消費者
const invoice = { TaxType: '1', // '1': 應稅 Print: '0', // '0': 不印 Donation: '0', // '0': 不捐贈 RelateNumber: '850b7a66-d575-11ec', InvoiceItemName: '超有感內衣|超無感內褲', InvoiceItemCount: '2|3', InvoiceItemWord: '件|件', InvoiceItemPrice: '100|50', // 預設都是含稅價 CustomerPhone: '0912345678', // 手機和 Eamil 須二擇一 // CustomerEmail: 'customer@example.com' };
-
買受人是有統編的營業人
const invoice = { TaxType: '1', // '1': 應稅 Print: '1', // '1': 只能選列印 Donation: '0', // '0': 只能選不捐贈 RelateNumber: '53ddd781-518e-456f', InvoiceItemName: '塑膠袋', InvoiceItemCount: '10', InvoiceItemWord: '包', InvoiceItemPrice: '15', // 預設都是含稅價 CustomerEmail: 'customer@example.com', // 手機和 Eamil 須二擇一 // CustomerPhone: '0912345678', CustomerIdentifier: '12345678', // 統編 CustomerName: 'NEA神秘開發公司', CustomerAddr: '宇宙市太陽區地球路1號', DelayDay: 3, // 收到款項後 3 天自動開立 };
import { Merchant } from 'node-ecpay-aio';
// Step 1: 建立特店
const merchant = new Merchant('Test', { // 生產環境請記得將 'Test' 改成 'Production'
MerchantID: 'your-merchant-id',
HashKey: 'your-merchant-hashkey',
HashIV: 'your-merchant-hashiv',
ReturnURL: 'https://api.test.com/your/hook',
});
// [使用情境一] Step 2: 特店建立 payment => Step 3: 結帳
const payment = merchant.createPayment(CreditOneTimePayment, {});
const htmlRedirectPostForm = await payment.checkout({
// 結帳時給予發票資訊即表示要開立發票
RelateNumber: 'order-123456',
TaxType: '1',
Donation: '0',
Print: '0',
InvoiceItemName: '鉛筆|橡皮擦',
InvoiceItemCount: '10|2',
InvoiceItemWord: '支|顆',
InvoiceItemPrice: '12|18',
DelayDay: 0,
});
// [使用情境二] Step 2: 特店建立 query => Step 3: 執行查詢
const tradeInfoQuery = merchant.createQuery(TradeInfoQuery, {
MerchantTradeNo: 'NEA12345678',
});
const tradeInfo = await tradeInfoQuery.read();
// [使用情境三] Step 2: 特店建立 action => Step 3: 執行操作
const reAuthAction = merchant.createAction(CreditCardPeriodAction, {
MerchantTradeNo: 'some-trade-no';
Action: 'ReAuth'
});
const reAuthResult = await reAuthAction.execute();