Skip to content

Commit d3a3d86

Browse files
author
Simen Li
committed
feature: placeOrder
1 parent 2ef8e0f commit d3a3d86

11 files changed

Lines changed: 227 additions & 10 deletions

src/__tests__/payments/ATMPayment.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Merchant } from '../../feature/Merchant';
33
import { ATMPayment } from '../../feature/Payment';
44
import { TEST_MERCHANT_CONFIG, TEST_BASE_PARAMS } from '../test_setting';
5+
import { getCurrentTaipeiTimeString } from '../../utils';
56

67
const MERCHANT_CONFIG_ASYNC = {
78
...TEST_MERCHANT_CONFIG,
@@ -76,3 +77,36 @@ describe('ATMPayment: Check Params Constraints', () => {
7677
}).toThrowError('must be less than or equal to 60');
7778
});
7879
});
80+
81+
describe('ATMPayment: html', () => {
82+
const merchant = new Merchant('Test', TEST_MERCHANT_CONFIG);
83+
84+
const baseParams: BasePaymentParams = {
85+
MerchantTradeNo: `nea${getCurrentTaipeiTimeString({ format: 'Serial' })}`,
86+
MerchantTradeDate: getCurrentTaipeiTimeString(),
87+
TotalAmount: 999,
88+
TradeDesc: 'node-ecpay-aio testing order for ATMPayment',
89+
ItemName: 'test item name',
90+
};
91+
92+
test('Checkout with ', async () => {
93+
const payment = merchant.createPayment(ATMPayment, baseParams, {
94+
// ChooseSubPayment: 'FIRST',
95+
ExpireDate: 7,
96+
});
97+
const html = await payment.checkout();
98+
// const html = await payment.checkout({
99+
// RelateNumber: 'rl-no-1',
100+
// TaxType: '1',
101+
// Donation: '0',
102+
// Print: '0',
103+
// InvoiceItemName: 'item1|item2',
104+
// InvoiceItemCount: '2|5',
105+
// InvoiceItemWord: '台|張',
106+
// InvoiceItemPrice: '100|50',
107+
// InvoiceRemark: '測試發票備註',
108+
// CustomerPhone: '0911111111',
109+
// });
110+
console.log(html);
111+
});
112+
});

src/__tests__/payments/CreditPeriodPayment.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,3 +335,39 @@ describe('PeriodType="Y": Check Params Constraints', () => {
335335
}).toThrowError('must be less than or equal to 9');
336336
});
337337
});
338+
339+
describe('CreditPeriodPayment: html', () => {
340+
const merchant = new Merchant('Test', TEST_MERCHANT_CONFIG);
341+
342+
const baseParams: BasePaymentParams = {
343+
MerchantTradeNo: 'necacc0001',
344+
MerchantTradeDate: '2022/05/13 15:33:20',
345+
TotalAmount: 999,
346+
TradeDesc: 'node-ecpay-aio testing order for CreditPeriodPayment',
347+
ItemName: 'test item name',
348+
};
349+
350+
test('Checkout with ', async () => {
351+
const payment = merchant.createPayment(CreditPeriodPayment, baseParams, {
352+
PeriodAmount: 999,
353+
PeriodType: 'M',
354+
Frequency: 1,
355+
ExecTimes: 99,
356+
// PeriodReturnURL: 'https://ap.example.com/api',
357+
});
358+
const html = await payment.checkout();
359+
// const html = await payment.checkout({
360+
// RelateNumber: 'rl-no-1',
361+
// TaxType: '1',
362+
// Donation: '0',
363+
// Print: '0',
364+
// InvoiceItemName: 'item1|item2',
365+
// InvoiceItemCount: '2|5',
366+
// InvoiceItemWord: '台|張',
367+
// InvoiceItemPrice: '100|50',
368+
// InvoiceRemark: '測試發票備註',
369+
// CustomerPhone: '0911111111',
370+
// });
371+
console.log(html);
372+
});
373+
});

src/feature/Payment.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import {
33
generateCheckMacValue,
44
generateRedirectPostForm,
55
getEncodedInvoice,
6+
parseIntegerFileds,
7+
PostRequest,
68
} from '../utils';
79
import {
810
ALLPaymentParamsSchema,
@@ -31,7 +33,9 @@ import {
3133
ALLPaymentParams,
3234
InvoiceParams,
3335
ECPayPaymentType,
36+
PaymentInfoData,
3437
} from '../types';
38+
import { PaymentInfoQuery } from './Query';
3539

3640
export class Payment<T> {
3741
merchant: Merchant;
@@ -92,6 +96,37 @@ export class Payment<T> {
9296

9397
return generateRedirectPostForm(this.apiUrl, postOrder);
9498
}
99+
100+
async _placeOrder(invoice?: InvoiceParams): Promise<PaymentInfoData> {
101+
const { MerchantID, HashKey, HashIV } = this.merchant.config;
102+
const postParams = {
103+
MerchantID,
104+
...this.params,
105+
};
106+
107+
const CheckMacValue = generateCheckMacValue(postParams, HashKey, HashIV);
108+
109+
try {
110+
const _result = await PostRequest<T>({
111+
apiUrl: this.apiUrl,
112+
params: {
113+
...postParams,
114+
CheckMacValue,
115+
},
116+
responseEncoding: 'utf8',
117+
});
118+
119+
const result = parseIntegerFileds(_result, ['TradeAmt', 'RtnCode']);
120+
121+
return this.merchant
122+
.createQuery(PaymentInfoQuery, {
123+
MerchantTradeNo: this.baseParams.MerchantTradeNo,
124+
})
125+
.read();
126+
} catch (err) {
127+
throw err;
128+
}
129+
}
95130
}
96131

97132
export class CreditOneTimePayment extends Payment<CreditOneTimePaymentParams> {
@@ -170,11 +205,17 @@ export class ATMPayment extends Payment<ATMPaymentParams> {
170205

171206
this.params.ClientRedirectURL =
172207
params.ClientRedirectURL ?? this.merchant.config.ClientRedirectURL;
208+
173209
this.params.PaymentInfoURL =
174210
params.PaymentInfoURL ?? this.merchant.config.PaymentInfoURL;
175211

176212
ATMPaymentParamsSchema.validateSync(this.params);
177213
}
214+
215+
async placeOrder(invoice?: InvoiceParams): Promise<PaymentInfoData> {
216+
this.params.ChooseSubPayment = this.params.ChooseSubPayment || 'BOT';
217+
return this._placeOrder(invoice);
218+
}
178219
}
179220

180221
export class CVSPayment extends Payment<CVSPaymentParams> {
@@ -188,11 +229,17 @@ export class CVSPayment extends Payment<CVSPaymentParams> {
188229

189230
this.params.ClientRedirectURL =
190231
params.ClientRedirectURL ?? this.merchant.config.ClientRedirectURL;
232+
191233
this.params.PaymentInfoURL =
192234
params.PaymentInfoURL ?? this.merchant.config.PaymentInfoURL;
193235

194236
CVSPaymentParamsSchema.validateSync(this.params);
195237
}
238+
239+
async placeOrder(invoice?: InvoiceParams): Promise<PaymentInfoData> {
240+
this.params.ChooseSubPayment = this.params.ChooseSubPayment || 'CVS';
241+
return this._placeOrder(invoice);
242+
}
196243
}
197244

198245
export class BARCODEPayment extends Payment<BARCODEPaymentParams> {
@@ -206,11 +253,17 @@ export class BARCODEPayment extends Payment<BARCODEPaymentParams> {
206253

207254
this.params.ClientRedirectURL =
208255
params.ClientRedirectURL ?? this.merchant.config.ClientRedirectURL;
256+
209257
this.params.PaymentInfoURL =
210258
params.PaymentInfoURL ?? this.merchant.config.PaymentInfoURL;
211259

212260
BARCODEPaymentParamsSchema.validateSync(this.params);
213261
}
262+
263+
async placeOrder(invoice?: InvoiceParams): Promise<PaymentInfoData> {
264+
this.params.ChooseSubPayment = this.params.ChooseSubPayment || 'BARCODE';
265+
return this._placeOrder(invoice);
266+
}
214267
}
215268

216269
export class AndroidPayPayment extends Payment<AndroidPayPaymentParams> {
@@ -241,6 +294,7 @@ export class ALLPayment extends Payment<Partial<ALLPaymentParams>> {
241294

242295
this.params.ClientRedirectURL =
243296
params.ClientRedirectURL ?? this.merchant.config.ClientRedirectURL;
297+
244298
this.params.PaymentInfoURL =
245299
params.PaymentInfoURL ?? this.merchant.config.PaymentInfoURL;
246300

src/schema/ATMPaymentParamsSchema.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import * as yup from 'yup';
22
const ATMPaymentParamsSchema = yup.object().shape({
3+
ChooseSubPayment: yup
4+
.string()
5+
.strict()
6+
.oneOf([
7+
'TAISHIN',
8+
'ESUN',
9+
'BOT',
10+
'FUBON',
11+
'CHINATRUST',
12+
'FIRST',
13+
'LAND',
14+
'CATHAY',
15+
'TACHONG',
16+
'PANHSIN',
17+
]),
318
ExpireDate: yup.number().integer().strict().min(1).max(60),
419
PaymentInfoURL: yup.string().max(200).url(),
520
ClientRedirectURL: yup.string().max(200).url(),

src/schema/BARCODEPaymentParamsSchema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as yup from 'yup';
22

33
const BARCODEPaymentParamsSchema = yup.object().shape({
4+
ChooseSubPayment: yup.string().strict().oneOf(['BARCODE']),
45
StoreExpireDate: yup.number().strict().min(1).max(30),
56
PaymentInfoURL: yup.string().max(200).url(),
67
ClientRedirectURL: yup.string().max(200).url(),

src/schema/CVSPaymentParamsSchema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import * as yup from 'yup';
22

33
const CVSPaymentParamsSchema = yup.object().shape({
4+
ChooseSubPayment: yup
5+
.string()
6+
.strict()
7+
.oneOf(['CVS', 'OK', 'FAMILY', 'HILIFE', 'IBON']),
48
StoreExpireDate: yup.number().integer().strict().min(1).max(43200),
59
PaymentInfoURL: yup.string().max(200).url(),
610
ClientRedirectURL: yup.string().max(200).url(),

src/schema/CreditPeriodPaymentParamsSchema.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const CreditPeriodPaymentParamsSchema = yup.object().shape({
3939
is: 'Y',
4040
then: (schema) => schema.max(9),
4141
}),
42-
PeriodReturnURL: yup.string().required().max(200).url(),
42+
PeriodReturnURL: yup.string().max(200).url(),
4343
});
4444

4545
export default CreditPeriodPaymentParamsSchema;

src/schema/FundingReconDetailQueryParamsSchema.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as yup from 'yup';
22

33
const FundingReconDetailQueryParamsSchema = yup.object().shape({
4-
PayDateType: yup.string().strict().required().oneOf(['fund', 'close', 'enter']),
4+
PayDateType: yup
5+
.string()
6+
.strict()
7+
.required()
8+
.oneOf(['fund', 'close', 'enter']),
59
StartDate: yup
610
.string()
711
.strict()
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
import * as yup from 'yup';
22

3-
const WebATMPaymentParamsSchema = yup.object().shape({});
3+
const WebATMPaymentParamsSchema = yup.object().shape({
4+
ChooseSubPayment: yup
5+
.string()
6+
.strict()
7+
.oneOf([
8+
'TAISHIN',
9+
'ESUN',
10+
'BOT',
11+
'FUBON',
12+
'CHINATRUST',
13+
'FIRST',
14+
'CATHAY',
15+
'MEGA',
16+
'LAND',
17+
'TACHONG',
18+
'SINOPAC',
19+
]),
20+
});
421

522
export default WebATMPaymentParamsSchema;

src/types/index.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,19 @@ export interface CreditPeriodPaymentParams extends CreditPaymentBaseParams {
118118
PeriodReturnURL?: string;
119119
}
120120

121-
export interface WebATMPaymentParams {}
121+
export interface WebATMPaymentParams {
122+
ChooseSubPayment?: WebATMSubPaymentType;
123+
}
122124

123125
export interface ATMPaymentParams {
126+
ChooseSubPayment?: ATMSubPaymentType;
124127
ExpireDate?: number;
125128
PaymentInfoURL?: string;
126129
ClientRedirectURL?: string;
127130
}
128131

129132
export interface CVSPaymentParams {
133+
ChooseSubPayment?: CVSSubPaymentType;
130134
StoreExpireDate?: number;
131135
PaymentInfoURL?: string;
132136
ClientRedirectURL?: string;
@@ -137,6 +141,7 @@ export interface CVSPaymentParams {
137141
}
138142

139143
export interface BARCODEPaymentParams {
144+
ChooseSubPayment?: BARCODESubPaymentType;
140145
StoreExpireDate?: number;
141146
PaymentInfoURL?: string;
142147
ClientRedirectURL?: string;
@@ -312,6 +317,34 @@ export interface PaymentInfoData {
312317
Barcode3?: string;
313318
}
314319

320+
export type WebATMSubPaymentType =
321+
| 'TAISHIN'
322+
| 'ESUN'
323+
| 'BOT'
324+
| 'FUBON'
325+
| 'CHINATRUST'
326+
| 'FIRST'
327+
| 'CATHAY'
328+
| 'MEGA'
329+
| 'LAND'
330+
| 'TACHONG'
331+
| 'SINOPAC';
332+
333+
export type ATMSubPaymentType =
334+
| 'TAISHIN'
335+
| 'ESUN'
336+
| 'BOT'
337+
| 'FUBON'
338+
| 'CHINATRUST'
339+
| 'FIRST'
340+
| 'LAND'
341+
| 'CATHAY'
342+
| 'TACHONG'
343+
| 'PANHSIN';
344+
345+
export type CVSSubPaymentType = 'CVS' | 'OK' | 'FAMILY' | 'HILIFE' | 'IBON';
346+
export type BARCODESubPaymentType = 'BARCODE';
347+
315348
export type ECPayInfoPaymentType =
316349
| 'WebATM_TAISHIN'
317350
| 'WebATM_ESUN'

0 commit comments

Comments
 (0)