@chevre/domain
Version:
Chevre Domain Library for Node.js
176 lines (175 loc) • 9.79 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.payMovieTicket = payMovieTicket;
const surfrock = require("@surfrock/sdk");
const http_status_1 = require("http-status");
const errorHandler_1 = require("../../../errorHandler");
const factory = require("../../../factory");
const onPayActionCompleted_1 = require("../any/onPayActionCompleted");
const factory_1 = require("./factory");
const getCredentials_1 = require("./getCredentials");
/**
* 決済カード決済
*/
function payMovieTicket(params, options) {
return (repos, settings) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h;
const { callOnPayActionCompleted } = options;
const paymentMethodId = (_a = params.object[0]) === null || _a === void 0 ? void 0 : _a.paymentMethod.paymentMethodId;
const paymentServiceId = (_b = params.object[0]) === null || _b === void 0 ? void 0 : _b.id;
const seatInfoSyncIn = yield payActionParams2seatInfoSyncIn(params)(repos);
const startingAction = (0, factory_1.createStartingPayAction)(params);
let recipe = (0, factory_1.processSeatInfoSyncResult2payRecipe)({
processSeatInfoSyncResult: { seatInfoSyncIn },
project: { id: params.project.id }
});
const action = yield repos.action.start(startingAction, { recipe });
let processSeatInfoSyncResult;
try {
// 着券済に対する冪等性を確保する必要はあるが、
// その他のアクションとしての振る舞いは実行される必要もある
const completedPayAction = yield repos.action.findPayAction({ project: { id: params.project.id }, paymentMethodId });
let payRecipe;
if (completedPayAction !== undefined) {
payRecipe = yield repos.action.findRecipeByAction({
project: { id: params.project.id },
recipeFor: { id: completedPayAction.id }
});
}
// すでに決済済であれば、何もしない(決済開始時の着券)
// const seatInfoSyncResultFromCompletedAction = completedPayAction?.result?.seatInfoSyncResult;
const seatInfoSyncResultFromCompletedAction = (_e = (_d = (_c = payRecipe === null || payRecipe === void 0 ? void 0 : payRecipe.step[0]) === null || _c === void 0 ? void 0 : _c.itemListElement[0]) === null || _d === void 0 ? void 0 : _d.itemListElement[0]) === null || _e === void 0 ? void 0 : _e.afterMedia;
if (seatInfoSyncResultFromCompletedAction !== undefined) {
processSeatInfoSyncResult = { seatInfoSyncIn, seatInfoSyncResult: seatInfoSyncResultFromCompletedAction };
}
else {
const availableChannel = yield repos.paymentService.findAvailableChannelMovieTicket({
project: params.project,
id: paymentServiceId
});
const mvtkReserveAuthClient = new surfrock.auth.ClientCredentials({
domain: String((_f = availableChannel.credentials) === null || _f === void 0 ? void 0 : _f.authorizeServerDomain),
clientId: String((_g = availableChannel.credentials) === null || _g === void 0 ? void 0 : _g.clientId),
clientSecret: String((_h = availableChannel.credentials) === null || _h === void 0 ? void 0 : _h.clientSecret),
scopes: [],
state: '',
credentialsRepo: repos.credentials // set credentialsRepo(2024-11-20~)
});
const seatService = new surfrock.service.seat.SeatService({ endpoint: String(availableChannel.serviceUrl), auth: mvtkReserveAuthClient }, { timeout: settings.movieticketReserve.timeout });
processSeatInfoSyncResult = yield processSeatInfoSync({ seatInfoSyncIn })({ seatService });
}
// add recipe(2024-06-03~)
recipe = (0, factory_1.processSeatInfoSyncResult2payRecipe)({
processSeatInfoSyncResult,
project: { id: params.project.id }
});
}
catch (error) {
// アクション保管用のエラーと両方保管(2024-05-22~)
const errors = [(0, errorHandler_1.handleMvtkReserveError)(error), error];
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error: errors });
}
catch (__) {
// 失敗したら仕方ない
}
throw errors;
}
// const seatInfoSyncResult = processSeatInfoSyncResult.seatInfoSyncResult;
const result = {
// discontinue(2024-06-10~)
// ...(seatInfoSyncResult !== undefined
// && (<factory.action.trade.pay.ISeatInfoSyncResult>seatInfoSyncResult).zskyykResult !== undefined)
// ? { seatInfoSyncResult: <factory.action.trade.pay.ISeatInfoSyncResult>seatInfoSyncResult }
// : undefined
};
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result, recipe });
if (callOnPayActionCompleted) {
yield (0, onPayActionCompleted_1.onPayActionCompleted)({
// actionStatus: factory.actionStatusType.CompletedActionStatus,
id: action.id,
object: startingAction.object,
potentialActions: startingAction.potentialActions,
project: startingAction.project,
purpose: startingAction.purpose,
typeOf: action.typeOf
})(repos);
}
});
}
function payActionParams2seatInfoSyncIn(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const paymentMethodType = (_a = params.object[0]) === null || _a === void 0 ? void 0 : _a.paymentMethod.typeOf;
const paymentMethodId = (_b = params.object[0]) === null || _b === void 0 ? void 0 : _b.paymentMethod.paymentMethodId;
const paymentServiceId = (_c = params.object[0]) === null || _c === void 0 ? void 0 : _c.id;
// イベントがひとつに特定されているかどうか確認
const eventIds = [...new Set(params.object.reduce((a, b) => [
...a,
...(Array.isArray(b.movieTickets)) ? b.movieTickets.map((ticket) => ticket.serviceOutput.reservationFor.id) : []
], []))];
if (eventIds.length !== 1) {
throw new factory.errors.Argument('movieTickets', 'Number of events must be 1');
}
const event = yield repos.event.projectEventFieldsById({ id: eventIds[0] },
// optimize projection(2024-07-19~)
[
'coaInfo', 'startDate', 'project',
'offers.offeredThrough', 'location.branchCode', 'superEvent.workPerformed.identifier'
]);
const sellerId = String((_d = params.recipient) === null || _d === void 0 ? void 0 : _d.id);
// 全購入管理番号のMovieTicketをマージ
const movieTickets = params.object.reduce((a, b) => [...a, ...(Array.isArray(b.movieTickets)) ? b.movieTickets : []], []);
const sellerCredentials = yield (0, getCredentials_1.getCredentials)({
seller: { id: sellerId, project: { id: event.project.id } },
paymentServiceId
})(repos);
const paymentAccepted = yield repos.paymentAccepted.isAcceptedBySeller({
seller: { id: sellerId },
codeValue: paymentMethodType
});
if (paymentAccepted !== true) {
throw new factory.errors.Argument('transactionId', `payment not accepted [${paymentMethodType}]`);
}
return (0, factory_1.createSeatInfoSyncIn)({
paymentMethodType: paymentMethodType,
paymentMethodId: paymentMethodId,
movieTickets: movieTickets,
event: event,
purpose: params.purpose,
credentials: sellerCredentials
});
});
}
function processSeatInfoSync(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
let seatInfoSyncResult;
const { seatInfoSyncIn } = params;
try {
seatInfoSyncResult = yield repos.seatService.seatInfoSync(seatInfoSyncIn);
}
catch (error) {
let throwsError = true;
// 「既に存在する興行システム座席予約番号が入力されました」の場合、着券済なのでok
if (error.name === errorHandler_1.MOVIE_TICKET_RESERVE_REQUEST_ERROR_NAME) {
if (error.code === http_status_1.BAD_REQUEST && error.message === factory_1.MovieticketReserveRequestErrorMessage.AlreadyPaid) {
seatInfoSyncResult = error;
throwsError = false;
}
}
if (throwsError) {
throw error;
}
}
return { seatInfoSyncIn, seatInfoSyncResult };
});
}
;