KG이니시스·토스페이먼츠·NICEPAY·KCP의 설정과 PC·모바일 주문서 버튼을 공통 목록으로 관리한다. 기본 PG 네이버페이가 비활성인 경우에만 KCP 병용 경로를 제공한다. 토스 직접 호출 선택값과 일반 카드 전환 초기화, NICEPAY 결제수단 변경 이벤트, 토스 머니·복합결제 현금영수증 저장을 보완한다. 설정 컬럼 확장 마이그레이션과 회귀 테스트를 추가한다. 검증: 변경 PHP 14개 문법 검사, PHP·JavaScript 회귀 테스트, 신규 설치와 마이그레이션 스키마 비교 통과. 실제 PG 승인·취소 및 운영 DB 마이그레이션은 미실행.
88 lines
5.2 KiB
JavaScript
88 lines
5.2 KiB
JavaScript
// 실행: node tests/pg_easypay.js (실제 PG SDK 대신 요청을 기록한다)
|
|
const fs = require('node:fs');
|
|
const vm = require('node:vm');
|
|
const assert = require('node:assert/strict');
|
|
const path = require('node:path');
|
|
const root = path.dirname(__dirname);
|
|
const providers = ['TOSSPAY', 'NAVERPAY', 'SAMSUNGPAY', 'APPLEPAY', 'LPAY', 'KAKAOPAY', 'PINPAY', 'PAYCO', 'SSG'];
|
|
function read(file) { return fs.readFileSync(path.join(root, file), 'utf8'); }
|
|
async function main() {
|
|
for (const [orderFile, sdkFile] of [
|
|
['shop/orderform.sub.php', 'shop/toss/orderform.1.php'],
|
|
['mobile/shop/orderform.sub.php', 'mobile/shop/toss/toss_approval.php'],
|
|
]) {
|
|
const source = read(orderFile);
|
|
const start = source.indexOf(" f.cardflowMode.value = 'DEFAULT';");
|
|
const end = source.indexOf(" f.amountCurrency.value", start);
|
|
const selectionCode = source.slice(start, end).replace(/<\?php[\s\S]*?\?>/g, JSON.stringify(providers));
|
|
let sdk = read(sdkFile);
|
|
sdk = sdk.slice(sdk.indexOf('async function launchCrossPlatform'), sdk.indexOf('await payment.requestPayment')) + 'await payment.requestPayment(paymentOptions);\n}';
|
|
sdk = sdk.replace(/<\?php[\s\S]*?\?>/g, 'https://example.test');
|
|
const requests = [];
|
|
let selected = '';
|
|
const context = vm.createContext({
|
|
payment: { requestPayment: async options => requests.push(options) },
|
|
$: () => ({ attr: () => selected }),
|
|
alert: message => { throw new Error(message); },
|
|
});
|
|
vm.runInContext(sdk + '\nfunction select(f, settle_method) {\n' + selectionCode + '\n}', context);
|
|
const form = {};
|
|
for (const key of ['amountValue', 'method', 'taxFreeAmount', 'orderId', 'orderName', 'customerEmail', 'customerName', 'customerMobilePhone', 'cardflowMode', 'cardeasyPay', 'cardUseCardPoint', 'cardUseAppCardOnly', 'cardUseEscrow', 'escrowProducts']) {
|
|
form[key] = { value: '' };
|
|
}
|
|
form.amountValue.value = '10000';
|
|
form.taxFreeAmount.value = '2000';
|
|
form.method.value = 'CARD';
|
|
form.cardUseEscrow.value = 'false';
|
|
for (const provider of providers) {
|
|
selected = provider;
|
|
context.select(form, '간편결제');
|
|
await context.launchCrossPlatform(form);
|
|
const direct = requests.at(-1);
|
|
assert.equal(direct.card.easyPay, provider);
|
|
assert.equal(direct.card.flowMode, 'DIRECT');
|
|
assert.equal(direct.amount.value, 10000);
|
|
assert.equal(direct.taxFreeAmount, 2000);
|
|
context.select(form, '신용카드');
|
|
await context.launchCrossPlatform(form);
|
|
const card = requests.at(-1);
|
|
assert.equal(card.card.flowMode, 'DEFAULT');
|
|
assert.equal('easyPay' in card.card, false);
|
|
}
|
|
selected = 'invalid';
|
|
assert.throws(() => context.select(form, '간편결제'), /다시 선택/);
|
|
// NICEPAY 선택 후 카드 재선택 시 직접 호출/에스크로 상태도 복원된다.
|
|
const niceStart = source.indexOf(' f.DirectShowOpt.value = "";');
|
|
let niceCode = source.slice(niceStart).replace(/<\?php[\s\S]*?\?>/g, '');
|
|
const niceContext = vm.createContext({ jQuery: () => ({ attr: () => selected }) });
|
|
// 모바일은 이 블록에 구매자 정보 복사 등이 이어지므로 switch 끝까지만 실행한다.
|
|
const switchStart = niceCode.indexOf('switch(settle_method)');
|
|
const braceStart = niceCode.indexOf('{', switchStart);
|
|
let depth = 1, braceEnd = braceStart + 1;
|
|
for (; depth && braceEnd < niceCode.length; braceEnd++) {
|
|
if (niceCode[braceEnd] === '{') depth++;
|
|
if (niceCode[braceEnd] === '}') depth--;
|
|
}
|
|
niceCode = niceCode.slice(0, braceEnd);
|
|
vm.runInContext('function select(f, settle_method) {\n' + niceCode + '\n}', niceContext);
|
|
const niceForm = {};
|
|
for (const key of ['DirectShowOpt', 'DirectEasyPay', 'NicepayReserved', 'EasyPayMethod', 'TransType', 'PayMethod']) niceForm[key] = { value: '' };
|
|
for (const [provider, field, code] of [
|
|
['nice_naverpay', 'DirectEasyPay', 'E020'], ['nice_samsungpay', 'DirectEasyPay', 'E021'],
|
|
['nice_kakaopay', 'NicepayReserved', 'DirectKakao=Y'], ['nice_paycopay', 'NicepayReserved', 'DirectPayco=Y'],
|
|
['nice_skpay', 'NicepayReserved', 'DirectPay11=Y'], ['nice_ssgpay', 'DirectEasyPay', 'E007'], ['nice_lpay', 'DirectEasyPay', 'E018'],
|
|
...(orderFile.startsWith('mobile') ? [['nice_applepay', 'DirectEasyPay', 'E022']] : []),
|
|
]) {
|
|
selected = provider;
|
|
niceContext.select(niceForm, '간편결제');
|
|
assert.equal(niceForm[field].value, code);
|
|
assert.equal(niceForm.TransType.value, '0');
|
|
niceContext.select(niceForm, '신용카드');
|
|
for (const key of ['DirectShowOpt', 'DirectEasyPay', 'NicepayReserved', 'EasyPayMethod']) assert.equal(niceForm[key].value, '');
|
|
assert.equal(niceForm.TransType.value, '1');
|
|
}
|
|
}
|
|
console.log('PC·모바일 PG 요청/결제수단 전환 테스트 통과');
|
|
}
|
|
main().catch(error => { console.error(error); process.exitCode = 1; });
|