@chevre/domain
Version:
Chevre Domain Library for Node.js
233 lines (232 loc) • 10.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.start = start;
exports.confirm = confirm;
exports.cancel = cancel;
exports.exportTasksById = exportTasksById;
/**
* 返金取引サービス
*/
const moment = require("moment");
const factory = require("../../factory");
const fixInformAction_1 = require("./fixInformAction");
const factory_1 = require("./refund/factory");
const potentialActions_1 = require("./refund/potentialActions");
/**
* 取引開始
*/
function start(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const paymentMethodId = (_a = params.object.paymentMethod) === null || _a === void 0 ? void 0 : _a.paymentMethodId;
if (typeof paymentMethodId !== 'string') {
throw new factory.errors.ArgumentNull('object.paymentMethod.paymentMethodId');
}
let paymentServiceType = (_b = params.object) === null || _b === void 0 ? void 0 : _b.typeOf;
// 必ず、決済取引からpaymentServiceTypeを取得する
const payTransaction = yield repos.assetTransaction.findByTransactionNumber({
typeOf: factory.assetTransactionType.Pay,
transactionNumber: paymentMethodId
});
paymentServiceType = payTransaction.object.typeOf;
// PayActionを確認する
const payAction = yield repos.action.findPayAction({ project: { id: params.project.id }, paymentMethodId });
if (payAction === undefined) {
throw new factory.errors.NotFound(factory.actionType.PayAction);
}
const transactionNumber = params.transactionNumber;
if (typeof transactionNumber !== 'string' || transactionNumber.length === 0) {
throw new factory.errors.ArgumentNull('transactionNumber');
}
// 決済サービス確認
const paymentService = yield fixPaymentService({ payAction, paymentServiceType })(repos);
const informActions = yield (0, fixInformAction_1.fixInformAction)({
paymentService,
project: { id: params.project.id }
})(repos);
// 取引開始
let transaction;
const startParams = (0, factory_1.createStartParams)(Object.assign(Object.assign({}, params), { transactionNumber,
payAction,
paymentService,
paymentServiceType,
informActions }));
try {
transaction = yield repos.assetTransaction.start(startParams);
switch (paymentServiceType) {
case factory.service.paymentService.PaymentServiceType.FaceToFace:
break;
case factory.service.paymentService.PaymentServiceType.PaymentCard:
break;
case factory.service.paymentService.PaymentServiceType.CreditCard:
break;
case factory.service.paymentService.PaymentServiceType.MovieTicket:
break;
default:
throw new factory.errors.NotImplemented(`Payment service '${paymentServiceType}' not implemented`);
}
}
catch (error) {
throw error;
}
return transaction;
});
}
function fixPaymentService(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const paymentServiceId = (Array.isArray(params.payAction.object) && params.payAction.object.length > 0)
? params.payAction.object[0].id
: '';
let paymentService;
switch (params.paymentServiceType) {
case factory.service.paymentService.PaymentServiceType.FaceToFace:
// no op
// FaceToFaceの場合プロダクトは存在しない
break;
// PaymentCardの場合、プロダクト検索
case factory.service.paymentService.PaymentServiceType.PaymentCard:
paymentService = (yield repos.product.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: params.payAction.project.id } },
typeOf: { $eq: factory.product.ProductType.PaymentCard },
id: { $eq: paymentServiceId }
}, ['availableChannel', 'typeOf', 'potentialAction']
// []
)).shift();
if (paymentService === undefined) {
throw new factory.errors.NotFound('PaymentService');
}
break;
default:
paymentService = (yield repos.paymentService.projectFields({
limit: 1,
page: 1,
project: { id: { $eq: params.payAction.project.id } },
typeOf: { $eq: params.paymentServiceType },
id: { $eq: paymentServiceId }
}, ['availableChannel', 'serviceOutput', 'typeOf', 'potentialAction'])).shift();
if (paymentService === undefined) {
throw new factory.errors.NotFound('PaymentService');
}
}
return paymentService;
});
}
/**
* 取引確定
*/
function confirm(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
let transaction;
// 取引存在確認
if (typeof params.id === 'string') {
transaction = yield repos.assetTransaction.findById({
typeOf: factory.assetTransactionType.Refund,
id: params.id
});
}
else if (typeof params.transactionNumber === 'string') {
transaction = yield repos.assetTransaction.findByTransactionNumber({
typeOf: factory.assetTransactionType.Refund,
transactionNumber: params.transactionNumber
});
}
else {
throw new factory.errors.ArgumentNull('Transaction ID or Transaction Number');
}
const payTransaction = (yield repos.assetTransaction.search({
limit: 1,
page: 1,
typeOf: factory.assetTransactionType.Pay,
transactionNumber: { $eq: transaction.object.paymentMethodId }
}, ['recipient'], [])).shift();
if (payTransaction === undefined) {
throw new factory.errors.NotFound(factory.assetTransactionType.Pay);
}
const potentialActions = yield (0, potentialActions_1.createPotentialActions)({
transaction: transaction,
seller: payTransaction.recipient,
potentialActions: params.potentialActions
});
yield repos.assetTransaction.confirm({
typeOf: factory.assetTransactionType.Refund,
id: transaction.id,
result: {},
potentialActions: potentialActions
});
});
}
/**
* 取引中止
*/
function cancel(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
yield repos.assetTransaction.cancel({
typeOf: factory.assetTransactionType.Refund,
id: params.id,
transactionNumber: params.transactionNumber
});
});
}
/**
* 取引のタスク出力
*/
function exportTasksById(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const transaction = yield repos.assetTransaction.findById({
typeOf: factory.assetTransactionType.Refund,
id: params.id
});
const potentialActions = transaction.potentialActions;
const taskAttributes = [];
// タスク実行日時バッファの指定があれば調整
let taskRunsAt = new Date();
if (typeof params.runsTasksAfterInSeconds === 'number') {
taskRunsAt = moment(taskRunsAt)
.add(params.runsTasksAfterInSeconds, 'seconds')
.toDate();
}
switch (transaction.status) {
case factory.transactionStatusType.Confirmed:
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (potentialActions !== undefined) {
// tslint:disable-next-line:no-single-line-block-comment
/* istanbul ignore else */
if (Array.isArray(potentialActions.refund)) {
const refundTasks = potentialActions.refund.map((a) => {
const data = Object.assign(Object.assign({}, a), { instrument: (Array.isArray(transaction.instrument)) ? transaction.instrument : [] });
return {
project: transaction.project,
name: factory.taskName.Refund,
status: factory.taskStatus.Ready,
runsAt: taskRunsAt,
remainingNumberOfTries: 10,
numberOfTried: 0,
executionResults: [],
data
};
});
taskAttributes.push(...refundTasks);
}
}
break;
case factory.transactionStatusType.Canceled:
case factory.transactionStatusType.Expired:
break;
default:
throw new factory.errors.NotImplemented(`Transaction status "${transaction.status}" not implemented.`);
}
return repos.task.saveMany(taskAttributes, { emitImmediately: true });
});
}
;