UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

233 lines (232 loc) 10.4 kB
"use strict"; 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 }); }); }