@cinerino/sdk 10.21.0-alpha.8 → 10.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example/playground/public/lib/bundle.js +1662 -943
- package/example/src/chevre/searchProjects.ts +17 -1
- package/example/src/cloud/transaction/processPlaceOrderByCreditCard3DS.ts +50 -3
- package/example/src/cloud/transaction/processPlaceOrderUsingMemberProgramTier.ts +517 -0
- package/example/src/findEventById.ts +12 -3
- package/lib/abstract/chevre/event.d.ts +3 -0
- package/lib/abstract/chevreAdmin/advanceBookingRequirement.d.ts +19 -0
- package/lib/abstract/chevreAdmin/{assetTransaction/refund.js → advanceBookingRequirement.js} +41 -37
- package/lib/abstract/chevreAdmin/assetTransaction/cancelReservation.d.ts +0 -13
- package/lib/abstract/chevreAdmin/assetTransaction/cancelReservation.js +9 -70
- package/lib/abstract/chevreAdmin/assetTransaction/pay.d.ts +0 -5
- package/lib/abstract/chevreAdmin/assetTransaction/pay.js +32 -51
- package/lib/abstract/chevreAdmin/eventOffer.d.ts +32 -0
- package/lib/abstract/chevreAdmin/eventOffer.js +169 -0
- package/lib/abstract/chevreAdmin/identity.d.ts +2 -2
- package/lib/abstract/chevreAdmin/identityProvider.d.ts +1 -1
- package/lib/abstract/chevreAdmin/identityProvider.js +2 -2
- package/lib/abstract/chevreAdmin/issuer.d.ts +12 -2
- package/lib/abstract/chevreAdmin/memberProgram.d.ts +38 -2
- package/lib/abstract/chevreAdmin/memberProgram.js +31 -4
- package/lib/abstract/chevreAdmin/offerCatalog.d.ts +8 -3
- package/lib/abstract/chevreAdmin/offerCatalogItem.d.ts +4 -3
- package/lib/abstract/chevreAdmin/paymentService.d.ts +18 -5
- package/lib/abstract/chevreAdmin/paymentServiceChannel.d.ts +2 -2
- package/lib/abstract/chevreAdmin/paymentServiceChannel.js +2 -2
- package/lib/abstract/chevreAdmin/pendingReservation.d.ts +58 -0
- package/lib/abstract/chevreAdmin/pendingReservation.js +104 -0
- package/lib/abstract/chevreAdmin/task.d.ts +2 -6
- package/lib/abstract/chevreAdmin/task.js +12 -13
- package/lib/abstract/chevreAdmin/webSite.d.ts +23 -0
- package/lib/abstract/chevreAdmin/webSite.js +138 -0
- package/lib/abstract/chevreAdmin.d.ts +36 -9
- package/lib/abstract/chevreAdmin.js +81 -20
- package/lib/abstract/chevrePay/payment/factory.d.ts +5 -5
- package/lib/abstract/cinerino/service/event.d.ts +7 -3
- package/lib/abstract/cinerino/service/event.js +24 -18
- package/lib/bundle.js +1716 -960
- package/package.json +2 -2
- package/example/src/chevre/assetTransaction/processCancelReservation.ts +0 -61
- package/example/src/chevre/assetTransaction/processPayMovieTicket.ts +0 -101
- package/example/src/chevre/assetTransaction/processPublishPaymentUrl.ts +0 -95
- package/example/src/chevre/assetTransaction/processRefundCreditCard.ts +0 -76
- package/lib/abstract/chevreAdmin/assetTransaction/refund.d.ts +0 -24
|
@@ -37,7 +37,23 @@ async function main() {
|
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
39
|
// tslint:disable-next-line:no-magic-numbers
|
|
40
|
-
|
|
40
|
+
1
|
|
41
|
+
);
|
|
42
|
+
setInterval(
|
|
43
|
+
async () => {
|
|
44
|
+
i += 1;
|
|
45
|
+
try {
|
|
46
|
+
const searchProjectsResult = await meService.searchProjects({
|
|
47
|
+
limit: 10,
|
|
48
|
+
page: 1
|
|
49
|
+
});
|
|
50
|
+
console.log(searchProjectsResult.data.length, 'projects returned', i);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(error, i);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
// tslint:disable-next-line:no-magic-numbers
|
|
56
|
+
1
|
|
41
57
|
);
|
|
42
58
|
}
|
|
43
59
|
|
|
@@ -48,7 +48,8 @@ async function main() {
|
|
|
48
48
|
// 新しい決済サービス
|
|
49
49
|
const paymentService = await (await client.loadCloudPay({
|
|
50
50
|
endpoint: <string>process.env.API_PAY_ENDPOINT,
|
|
51
|
-
auth: await auth()
|
|
51
|
+
auth: await auth(),
|
|
52
|
+
disableAutoRetry: true
|
|
52
53
|
})).createPaymentInstance({
|
|
53
54
|
project,
|
|
54
55
|
seller: { id: '' }
|
|
@@ -128,6 +129,25 @@ async function main() {
|
|
|
128
129
|
})({ paymentService });
|
|
129
130
|
console.log('paymentUrl published.', paymentMethodId, paymentUrl);
|
|
130
131
|
|
|
132
|
+
try {
|
|
133
|
+
const publishPaymentUrlAsyncForciblySecondResult = await publishPaymentUrlAsyncForcibly({
|
|
134
|
+
object: {
|
|
135
|
+
amount,
|
|
136
|
+
paymentMethod: paymentMethodType,
|
|
137
|
+
method: '1',
|
|
138
|
+
creditCard: {
|
|
139
|
+
...creditCard,
|
|
140
|
+
retUrl: String(process.env.SECURE_TRAN_RET_URL) // callbackを指定すると3DSとして処理される
|
|
141
|
+
},
|
|
142
|
+
issuedThrough: { id: paymentServiceId }
|
|
143
|
+
},
|
|
144
|
+
purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
145
|
+
})({ paymentService });
|
|
146
|
+
console.log('paymentUrl published.', publishPaymentUrlAsyncForciblySecondResult);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error('publishPaymentUrlAsyncForciblySecond:', error);
|
|
149
|
+
}
|
|
150
|
+
|
|
131
151
|
// wait callback...
|
|
132
152
|
await new Promise<void>((resolve, reject) => {
|
|
133
153
|
const rl = readline.createInterface({
|
|
@@ -135,8 +155,14 @@ async function main() {
|
|
|
135
155
|
output: process.stdout
|
|
136
156
|
});
|
|
137
157
|
|
|
138
|
-
rl.question('callback received
|
|
158
|
+
rl.question('callback received? y or n:\n', async (answer) => {
|
|
139
159
|
try {
|
|
160
|
+
if (answer !== 'y') {
|
|
161
|
+
reject(new Error('answer is no'));
|
|
162
|
+
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
140
166
|
console.log('authorizing credit card payment...');
|
|
141
167
|
const creditCardPaymentAuth = await authorizeCreditCardAsyncForcibly({
|
|
142
168
|
object: {
|
|
@@ -154,6 +180,7 @@ async function main() {
|
|
|
154
180
|
|
|
155
181
|
// tslint:disable-next-line:no-magic-numbers
|
|
156
182
|
await wait(3000);
|
|
183
|
+
// throw new Error('unexpected error');
|
|
157
184
|
|
|
158
185
|
console.log('setting customer profile...');
|
|
159
186
|
await placeOrderService.setProfile({
|
|
@@ -409,7 +436,27 @@ function authorizeCreditCardAsyncForcibly(params: {
|
|
|
409
436
|
paymentService: client.cloudPay.service.Payment;
|
|
410
437
|
}): Promise<{ id: string }> => {
|
|
411
438
|
// 決済承認タスク作成
|
|
412
|
-
const authorizeTask = await
|
|
439
|
+
const authorizeTask = await new Promise<{ id: string }>((resolve, reject) => {
|
|
440
|
+
repos.paymentService.authorizeCreditCardAsync(params)
|
|
441
|
+
.then(async (task) => {
|
|
442
|
+
console.log('waiting resolve authorizeCreditCardAsync...');
|
|
443
|
+
await wait(5000);
|
|
444
|
+
|
|
445
|
+
resolve(task);
|
|
446
|
+
})
|
|
447
|
+
.catch(reject);
|
|
448
|
+
// 再度承認してみる
|
|
449
|
+
// repos.paymentService.authorizeCreditCardAsync(params)
|
|
450
|
+
// .then(async (task) => {
|
|
451
|
+
// console.log('authorizeCreditCardAsync:', task);
|
|
452
|
+
// })
|
|
453
|
+
// .catch((authorizeCreditCardAsyncError) => {
|
|
454
|
+
// // 同paymentMethodIdでは承認できないはず
|
|
455
|
+
// console.error('authorizeCreditCardAsync:', authorizeCreditCardAsyncError);
|
|
456
|
+
// });
|
|
457
|
+
|
|
458
|
+
});
|
|
459
|
+
|
|
413
460
|
const giveUpPayment = moment()
|
|
414
461
|
.add(USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_GIVE_UP_SECONDS, 'seconds');
|
|
415
462
|
let result: { id: string } | undefined;
|
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
// tslint:disable:no-console no-implicit-dependencies no-magic-numbers
|
|
2
|
+
import * as moment from 'moment';
|
|
3
|
+
import * as readline from 'readline';
|
|
4
|
+
import * as client from '../../../../lib/index';
|
|
5
|
+
import { auth } from '../../auth/clientCredentials';
|
|
6
|
+
|
|
7
|
+
const { EVENT_ID, MEMBER_PROGRAM_TIER_TOKEN } = process.env;
|
|
8
|
+
const project = { id: String(process.env.PROJECT_ID) };
|
|
9
|
+
const profile = {
|
|
10
|
+
email: <string>process.env.TEST_PROFILE_EMAIL,
|
|
11
|
+
givenName: 'Taro',
|
|
12
|
+
familyName: 'SDK',
|
|
13
|
+
name: 'Taro ☆ SDK',
|
|
14
|
+
telephone: '+819012345678'
|
|
15
|
+
};
|
|
16
|
+
const paymentMethodType = 'CreditCard3DS';
|
|
17
|
+
const paymentServiceId = '664d98376fb87922bd6a4e52';
|
|
18
|
+
// 取引に使用するクレジットカード
|
|
19
|
+
const creditCard: client.factory.paymentMethod.paymentCard.creditCard.IUncheckedCardRaw = {
|
|
20
|
+
cardNo: '4100000000000100',
|
|
21
|
+
expire: '2812',
|
|
22
|
+
cardPass: '123',
|
|
23
|
+
holderName: 'AA AA'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// tslint:disable-next-line:max-func-body-length
|
|
27
|
+
async function main() {
|
|
28
|
+
const eventService = new (await client.loadService()).Event({
|
|
29
|
+
endpoint: <string>process.env.API_ENDPOINT,
|
|
30
|
+
auth: await auth(),
|
|
31
|
+
project,
|
|
32
|
+
seller: { id: '' }
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const sellerService = new (await client.loadService()).Seller({
|
|
36
|
+
endpoint: <string>process.env.API_ENDPOINT,
|
|
37
|
+
auth: await auth(),
|
|
38
|
+
project
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const placeOrderService = await (await client.loadCloudTxn({
|
|
42
|
+
endpoint: <string>process.env.API_TXN_ENDPOINT,
|
|
43
|
+
auth: await auth()
|
|
44
|
+
})).createPlaceOrderInstance({
|
|
45
|
+
project,
|
|
46
|
+
seller: { id: '' }
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// 新しい決済サービス
|
|
50
|
+
const paymentService = await (await client.loadCloudPay({
|
|
51
|
+
endpoint: <string>process.env.API_PAY_ENDPOINT,
|
|
52
|
+
auth: await auth(),
|
|
53
|
+
disableAutoRetry: true
|
|
54
|
+
})).createPaymentInstance({
|
|
55
|
+
project,
|
|
56
|
+
seller: { id: '' }
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 販売劇場検索
|
|
60
|
+
const searchSellersResult = await sellerService.search({ branchCode: { $eq: '001' } });
|
|
61
|
+
// tslint:disable-next-line:insecure-random
|
|
62
|
+
const seller = searchSellersResult.data[Math.floor(searchSellersResult.data.length * Math.random())];
|
|
63
|
+
if (seller === undefined) {
|
|
64
|
+
throw new Error('No seller');
|
|
65
|
+
}
|
|
66
|
+
console.log('ordering from seller...', (<client.factory.multilingualString>seller.name).ja);
|
|
67
|
+
|
|
68
|
+
// イベント検索
|
|
69
|
+
const searchScreeningEventsResult = await eventService.search<client.factory.eventType.ScreeningEvent>({
|
|
70
|
+
id: { $eq: EVENT_ID },
|
|
71
|
+
typeOf: client.factory.eventType.ScreeningEvent,
|
|
72
|
+
inSessionFrom: moment()
|
|
73
|
+
.toDate(),
|
|
74
|
+
inSessionThrough: moment()
|
|
75
|
+
.add(1, 'week')
|
|
76
|
+
.toDate()
|
|
77
|
+
});
|
|
78
|
+
console.log(searchScreeningEventsResult.data.length, 'events found');
|
|
79
|
+
|
|
80
|
+
const availableEvents = searchScreeningEventsResult.data;
|
|
81
|
+
if (availableEvents.length === 0) {
|
|
82
|
+
throw new Error('No available events');
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('starting transaction...');
|
|
86
|
+
const transaction = await placeOrderService.start({
|
|
87
|
+
agent: {
|
|
88
|
+
identifier: [
|
|
89
|
+
{ name: 'fromSamples', value: 'true' }
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
seller: { id: String(seller.id) },
|
|
93
|
+
object: {
|
|
94
|
+
// passport: { token: passportToken }
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
console.log('transaction started', transaction.id);
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
const numEvents = 1;
|
|
101
|
+
let amount = 0;
|
|
102
|
+
// tslint:disable-next-line:max-line-length
|
|
103
|
+
const authorizeSeatReservationResults: { price: number }[] = [];
|
|
104
|
+
|
|
105
|
+
// tslint:disable-next-line:no-increment-decrement
|
|
106
|
+
for (let i = 0; i < numEvents; i++) {
|
|
107
|
+
// イベント決定
|
|
108
|
+
// tslint:disable-next-line:insecure-random
|
|
109
|
+
const screeningEvent = availableEvents[Math.floor(availableEvents.length * Math.random())];
|
|
110
|
+
const authorizeSeatReservationResult = await authorizeSeatReservationByEvent({
|
|
111
|
+
event: screeningEvent,
|
|
112
|
+
transaction: transaction
|
|
113
|
+
});
|
|
114
|
+
amount += Number(authorizeSeatReservationResult.price);
|
|
115
|
+
authorizeSeatReservationResults.push(authorizeSeatReservationResult);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 決済URL発行
|
|
119
|
+
const { paymentMethodId, paymentUrl } = await publishPaymentUrlAsyncForcibly({
|
|
120
|
+
object: {
|
|
121
|
+
amount,
|
|
122
|
+
paymentMethod: paymentMethodType,
|
|
123
|
+
method: '1',
|
|
124
|
+
creditCard: {
|
|
125
|
+
...creditCard,
|
|
126
|
+
retUrl: String(process.env.SECURE_TRAN_RET_URL) // callbackを指定すると3DSとして処理される
|
|
127
|
+
},
|
|
128
|
+
issuedThrough: { id: paymentServiceId }
|
|
129
|
+
},
|
|
130
|
+
purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
131
|
+
})({ paymentService });
|
|
132
|
+
console.log('paymentUrl published.', paymentMethodId, paymentUrl);
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const publishPaymentUrlAsyncForciblySecondResult = await publishPaymentUrlAsyncForcibly({
|
|
136
|
+
object: {
|
|
137
|
+
amount,
|
|
138
|
+
paymentMethod: paymentMethodType,
|
|
139
|
+
method: '1',
|
|
140
|
+
creditCard: {
|
|
141
|
+
...creditCard,
|
|
142
|
+
retUrl: String(process.env.SECURE_TRAN_RET_URL) // callbackを指定すると3DSとして処理される
|
|
143
|
+
},
|
|
144
|
+
issuedThrough: { id: paymentServiceId }
|
|
145
|
+
},
|
|
146
|
+
purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
147
|
+
})({ paymentService });
|
|
148
|
+
console.log('paymentUrl published.', publishPaymentUrlAsyncForciblySecondResult);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error('publishPaymentUrlAsyncForciblySecond:', error);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// wait callback...
|
|
154
|
+
await new Promise<void>((resolve, reject) => {
|
|
155
|
+
const rl = readline.createInterface({
|
|
156
|
+
input: process.stdin,
|
|
157
|
+
output: process.stdout
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
rl.question('callback received? y or n:\n', async (answer) => {
|
|
161
|
+
try {
|
|
162
|
+
if (answer !== 'y') {
|
|
163
|
+
reject(new Error('answer is no'));
|
|
164
|
+
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log('authorizing credit card payment...');
|
|
169
|
+
const creditCardPaymentAuth = await authorizeCreditCardAsyncForcibly({
|
|
170
|
+
object: {
|
|
171
|
+
amount,
|
|
172
|
+
// amount: 1, // 間違えてみる
|
|
173
|
+
paymentMethod: paymentMethodType,
|
|
174
|
+
paymentMethodId, // URL発行時のpaymentMethodIdを指定
|
|
175
|
+
method: '1',
|
|
176
|
+
creditCard,
|
|
177
|
+
issuedThrough: { id: paymentServiceId }
|
|
178
|
+
},
|
|
179
|
+
purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
180
|
+
})({ paymentService });
|
|
181
|
+
console.log('credit card payment authorized', creditCardPaymentAuth.id);
|
|
182
|
+
|
|
183
|
+
// tslint:disable-next-line:no-magic-numbers
|
|
184
|
+
await wait(3000);
|
|
185
|
+
// throw new Error('unexpected error');
|
|
186
|
+
|
|
187
|
+
console.log('setting customer profile...');
|
|
188
|
+
await placeOrderService.setProfile({
|
|
189
|
+
id: transaction.id,
|
|
190
|
+
agent: profile
|
|
191
|
+
});
|
|
192
|
+
console.log('customer profile set');
|
|
193
|
+
|
|
194
|
+
await wait(3000);
|
|
195
|
+
|
|
196
|
+
// console.log('voiding credit card auth...');
|
|
197
|
+
// await paymentService.voidTransaction({
|
|
198
|
+
// id: creditCardPaymentAuth.id,
|
|
199
|
+
// object: { typeOf: client.factory.service.paymentService.PaymentServiceType.CreditCard },
|
|
200
|
+
// purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
201
|
+
// });
|
|
202
|
+
// console.log('credit card auth voided');
|
|
203
|
+
// await wait(3000);
|
|
204
|
+
// return;
|
|
205
|
+
|
|
206
|
+
console.log('confirming transaction...');
|
|
207
|
+
|
|
208
|
+
let confirmResult = await placeOrderService.confirmWithMiminalResponse({ id: transaction.id });
|
|
209
|
+
console.log('transaction confirmed', confirmResult);
|
|
210
|
+
|
|
211
|
+
// 何度確定をコールしても冪等
|
|
212
|
+
console.log('reconfirming transaction...');
|
|
213
|
+
confirmResult = await placeOrderService.confirmWithMiminalResponse({ id: transaction.id });
|
|
214
|
+
console.log('transaction reconfirmed', confirmResult);
|
|
215
|
+
resolve();
|
|
216
|
+
} catch (error) {
|
|
217
|
+
reject(error);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error(error);
|
|
223
|
+
|
|
224
|
+
await wait(3000);
|
|
225
|
+
|
|
226
|
+
console.log('canceling transaction...');
|
|
227
|
+
await placeOrderService.cancel({ id: transaction.id });
|
|
228
|
+
console.log('transaction canceled.');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
type IAuthorizeReservationAction = Pick<client.factory.action.authorize.offer.eventService.IAction, 'id'> & {
|
|
233
|
+
result?: {
|
|
234
|
+
price?: number;
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// tslint:disable-next-line:max-func-body-length
|
|
239
|
+
async function authorizeSeatReservationByEvent(params: {
|
|
240
|
+
event: Omit<client.factory.event.screeningEvent.IEvent, 'offers'>;
|
|
241
|
+
transaction: Pick<client.factory.transaction.placeOrder.ITransaction, 'id'>;
|
|
242
|
+
}): Promise<{
|
|
243
|
+
price: number;
|
|
244
|
+
}> {
|
|
245
|
+
const eventService = new (await client.loadService()).Event({
|
|
246
|
+
endpoint: <string>process.env.API_ENDPOINT,
|
|
247
|
+
auth: await auth(),
|
|
248
|
+
project,
|
|
249
|
+
seller: { id: '' }
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const offerService = await (await client.loadCloudTxn({
|
|
253
|
+
endpoint: <string>process.env.API_TXN_ENDPOINT,
|
|
254
|
+
auth: await auth()
|
|
255
|
+
})).createOfferInstance({
|
|
256
|
+
project,
|
|
257
|
+
seller: { id: '' }
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
const screeningEvent = params.event;
|
|
261
|
+
const transaction = params.transaction;
|
|
262
|
+
|
|
263
|
+
// 券種検索
|
|
264
|
+
let ticketOffers = await eventService.searchTicketOffers({
|
|
265
|
+
event: { id: screeningEvent.id }
|
|
266
|
+
});
|
|
267
|
+
console.log('チケットオファーは以下の通りです');
|
|
268
|
+
console.log(ticketOffers.map((o) => {
|
|
269
|
+
const unitPriceSpecification = o.priceSpecification.priceComponent
|
|
270
|
+
.filter((s) => s.typeOf === client.factory.priceSpecificationType.UnitPriceSpecification)
|
|
271
|
+
.map((s) => `単価:${s.price}/${(<client.factory.priceSpecification.IPriceSpecification<client.factory.priceSpecificationType.UnitPriceSpecification>>s).referenceQuantity.value}`)
|
|
272
|
+
.join(' ');
|
|
273
|
+
const categoryCodeCharge = o.priceSpecification.priceComponent
|
|
274
|
+
.filter((s) => s.typeOf === client.factory.priceSpecificationType.CategoryCodeChargeSpecification)
|
|
275
|
+
.map((s) => `+${(<client.factory.priceSpecification.IPriceSpecification<client.factory.priceSpecificationType.CategoryCodeChargeSpecification>>s).appliesToCategoryCode[0].codeValue}チャージ:${s.price} ${s.priceCurrency}`)
|
|
276
|
+
.join(' ');
|
|
277
|
+
|
|
278
|
+
return `${o.id} ${(<client.factory.multilingualString>o.name).ja} ${unitPriceSpecification} ${categoryCodeCharge}`;
|
|
279
|
+
})
|
|
280
|
+
.join('\n'));
|
|
281
|
+
|
|
282
|
+
// 空席検索
|
|
283
|
+
const searchSeatOffersResult = await eventService.searchSeats({
|
|
284
|
+
event: { id: screeningEvent.id },
|
|
285
|
+
limit: 100,
|
|
286
|
+
page: 1
|
|
287
|
+
});
|
|
288
|
+
const seatOffers = searchSeatOffersResult.data;
|
|
289
|
+
// console.log(seatOffers.length, 'seatOffers found');
|
|
290
|
+
// const seatOffers = offers[0].containsPlace;
|
|
291
|
+
console.log(seatOffers.length, 'seatOffers found');
|
|
292
|
+
const availableSeatOffers
|
|
293
|
+
= seatOffers.filter((o) => o.offers?.shift()?.availability === client.factory.itemAvailability.InStock);
|
|
294
|
+
console.log(availableSeatOffers.length, 'availableSeatOffers found');
|
|
295
|
+
if (availableSeatOffers.length <= 0) {
|
|
296
|
+
throw new Error('No available seats');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// ムビチケ以外のメンバーシップオファーを選択
|
|
300
|
+
ticketOffers = ticketOffers
|
|
301
|
+
.filter((offer) => {
|
|
302
|
+
const movieTicketTypeChargeSpecification = offer.priceSpecification.priceComponent.find(
|
|
303
|
+
(component) => component.typeOf === client.factory.priceSpecificationType.MovieTicketTypeChargeSpecification
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
return movieTicketTypeChargeSpecification === undefined;
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const selectedTicketOffer = ticketOffers.shift();
|
|
310
|
+
if (selectedTicketOffer === undefined) {
|
|
311
|
+
throw new Error('selectedTicketOffer undefined');
|
|
312
|
+
}
|
|
313
|
+
console.log('ticket offer selected', selectedTicketOffer.id, selectedTicketOffer.identifier, selectedTicketOffer.name.ja);
|
|
314
|
+
|
|
315
|
+
// 座席をランダムに選択
|
|
316
|
+
const selectedScreeningRoomSection = String(availableSeatOffers[0].containedInPlace?.branchCode);
|
|
317
|
+
console.log('screening room section selected', selectedScreeningRoomSection);
|
|
318
|
+
console.log(selectedScreeningRoomSection);
|
|
319
|
+
const selectedSeatOffers = availableSeatOffers.slice(0, 1);
|
|
320
|
+
console.log(selectedSeatOffers.length, 'seats selected');
|
|
321
|
+
|
|
322
|
+
await wait(3000);
|
|
323
|
+
console.log('authorizing seat reservation...');
|
|
324
|
+
const seatReservationAuth = <IAuthorizeReservationAction>await offerService.authorizeEventService({
|
|
325
|
+
object: {
|
|
326
|
+
reservationFor: {
|
|
327
|
+
id: screeningEvent.id,
|
|
328
|
+
offers: { validForMemberTier: MEMBER_PROGRAM_TIER_TOKEN }
|
|
329
|
+
},
|
|
330
|
+
acceptedOffer: selectedSeatOffers.map((o) => {
|
|
331
|
+
return {
|
|
332
|
+
typeOf: selectedTicketOffer.typeOf,
|
|
333
|
+
id: String(selectedTicketOffer.id),
|
|
334
|
+
itemOffered: {
|
|
335
|
+
serviceOutput: {
|
|
336
|
+
typeOf: client.factory.reservationType.EventReservation,
|
|
337
|
+
reservedTicket: {
|
|
338
|
+
typeOf: 'Ticket',
|
|
339
|
+
ticketedSeat: {
|
|
340
|
+
typeOf: client.factory.placeType.Seat,
|
|
341
|
+
seatNumber: o.branchCode,
|
|
342
|
+
seatSection: selectedScreeningRoomSection,
|
|
343
|
+
seatRow: ''
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
additionalProperty: [{ name: 'sampleName', value: 'sampleValue' }]
|
|
349
|
+
};
|
|
350
|
+
})
|
|
351
|
+
},
|
|
352
|
+
purpose: { id: transaction.id, typeOf: client.factory.transactionType.PlaceOrder }
|
|
353
|
+
});
|
|
354
|
+
console.log('seat reservation authorized', seatReservationAuth.id);
|
|
355
|
+
|
|
356
|
+
const price = seatReservationAuth.result?.price;
|
|
357
|
+
// 金額計算
|
|
358
|
+
if (typeof price !== 'number') {
|
|
359
|
+
throw new Error('result.price undefined');
|
|
360
|
+
}
|
|
361
|
+
console.log('price:', price);
|
|
362
|
+
|
|
363
|
+
return { price };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async function wait(waitInMilliseconds: number) {
|
|
367
|
+
return new Promise((resolve) => setTimeout(resolve, waitInMilliseconds));
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_GIVE_UP_SECONDS = 10;
|
|
371
|
+
const USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_CHECK_INTERVAL_MS = 1000;
|
|
372
|
+
function publishPaymentUrlAsyncForcibly(params: {
|
|
373
|
+
object: Pick<client.factory.action.authorize.paymentMethod.any.IObjectWithoutDetail, 'amount' | 'creditCard' | 'issuedThrough' | 'paymentMethod' | 'method'>;
|
|
374
|
+
purpose: {
|
|
375
|
+
typeOf: client.factory.transactionType.PlaceOrder;
|
|
376
|
+
id: string;
|
|
377
|
+
};
|
|
378
|
+
}) {
|
|
379
|
+
return async (repos: {
|
|
380
|
+
paymentService: client.cloudPay.service.Payment;
|
|
381
|
+
}): Promise<client.factory.action.accept.pay.IResult> => {
|
|
382
|
+
const acceptTask = await repos.paymentService.publishCreditCardPaymentUrlAsync(params);
|
|
383
|
+
const giveUpPayment = moment()
|
|
384
|
+
.add(USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_GIVE_UP_SECONDS, 'seconds');
|
|
385
|
+
let result: client.factory.action.accept.pay.IResult | undefined;
|
|
386
|
+
let error: { name?: string; message?: string } | undefined;
|
|
387
|
+
|
|
388
|
+
// n秒おきに状態確認
|
|
389
|
+
while (result === undefined && error === undefined) {
|
|
390
|
+
await wait(USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_CHECK_INTERVAL_MS); // n秒待機
|
|
391
|
+
|
|
392
|
+
// タスク作成から一定時間経過すればあきらめる
|
|
393
|
+
if (moment()
|
|
394
|
+
.isAfter(giveUpPayment)) {
|
|
395
|
+
error = new client.factory.errors.GatewayTimeout('action given up');
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const acceptAction = await repos.paymentService.findAcceptPayAction({
|
|
400
|
+
sameAs: { id: acceptTask.id },
|
|
401
|
+
purpose: params.purpose
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// CompletedActionStatusであればタスク完了とみなす
|
|
405
|
+
if (acceptAction.actionStatus === client.factory.actionStatusType.CompletedActionStatus
|
|
406
|
+
&& acceptAction.result !== undefined) {
|
|
407
|
+
result = acceptAction.result;
|
|
408
|
+
break;
|
|
409
|
+
} else {
|
|
410
|
+
// 待機続行
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// エラーが存在すれば、これ以上待機する価値はなし
|
|
414
|
+
if (acceptAction.error !== undefined) {
|
|
415
|
+
error = acceptAction.error;
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (typeof result?.paymentMethodId === 'string') {
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
throw error;
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function authorizeCreditCardAsyncForcibly(params: {
|
|
429
|
+
object: Pick<
|
|
430
|
+
client.factory.action.authorize.paymentMethod.any.IObjectWithoutDetail,
|
|
431
|
+
'amount' | 'issuedThrough' | 'paymentMethod' | 'creditCard' | 'method' | 'paymentMethodId' | 'name' | 'additionalProperty'
|
|
432
|
+
>;
|
|
433
|
+
purpose: {
|
|
434
|
+
typeOf: client.factory.transactionType.PlaceOrder;
|
|
435
|
+
id: string;
|
|
436
|
+
};
|
|
437
|
+
}) {
|
|
438
|
+
return async (repos: {
|
|
439
|
+
paymentService: client.cloudPay.service.Payment;
|
|
440
|
+
}): Promise<{ id: string }> => {
|
|
441
|
+
// 決済承認タスク作成
|
|
442
|
+
const authorizeTask = await new Promise<{ id: string }>((resolve, reject) => {
|
|
443
|
+
repos.paymentService.authorizeCreditCardAsync(params)
|
|
444
|
+
.then(async (task) => {
|
|
445
|
+
console.log('waiting resolve authorizeCreditCardAsync...');
|
|
446
|
+
await wait(5000);
|
|
447
|
+
|
|
448
|
+
resolve(task);
|
|
449
|
+
})
|
|
450
|
+
.catch(reject);
|
|
451
|
+
// 再度承認してみる
|
|
452
|
+
// repos.paymentService.authorizeCreditCardAsync(params)
|
|
453
|
+
// .then(async (task) => {
|
|
454
|
+
// console.log('authorizeCreditCardAsync:', task);
|
|
455
|
+
// })
|
|
456
|
+
// .catch((authorizeCreditCardAsyncError) => {
|
|
457
|
+
// // 同paymentMethodIdでは承認できないはず
|
|
458
|
+
// console.error('authorizeCreditCardAsync:', authorizeCreditCardAsyncError);
|
|
459
|
+
// });
|
|
460
|
+
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
const giveUpPayment = moment()
|
|
464
|
+
.add(USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_GIVE_UP_SECONDS, 'seconds');
|
|
465
|
+
let result: { id: string } | undefined;
|
|
466
|
+
let error: { name?: string; message?: string } | undefined;
|
|
467
|
+
|
|
468
|
+
// n秒おきに状態確認
|
|
469
|
+
while (result === undefined && error === undefined) {
|
|
470
|
+
await wait(USE_FORCE_AUTHORIZE_PAYMENT_ASYNC_CHECK_INTERVAL_MS); // n秒待機
|
|
471
|
+
|
|
472
|
+
// タスク作成から一定時間経過すればあきらめる
|
|
473
|
+
if (moment()
|
|
474
|
+
.isAfter(giveUpPayment)) {
|
|
475
|
+
error = new client.factory.errors.GatewayTimeout('action given up');
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const authorizeAction = await repos.paymentService.findAuthorizeAction({
|
|
480
|
+
sameAs: { id: authorizeTask.id },
|
|
481
|
+
object: {
|
|
482
|
+
typeOf: client.factory.service.paymentService.PaymentServiceType.CreditCard
|
|
483
|
+
},
|
|
484
|
+
purpose: params.purpose
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// アクションIDが存在し、CompletedActionStatusであればタスク完了とみなす
|
|
488
|
+
if (typeof authorizeAction.id === 'string') {
|
|
489
|
+
if (authorizeAction.actionStatus === client.factory.actionStatusType.CompletedActionStatus) {
|
|
490
|
+
// ステータス完了であれば決済承認アクションIDを保管
|
|
491
|
+
result = { id: authorizeAction.id };
|
|
492
|
+
break;
|
|
493
|
+
} else {
|
|
494
|
+
// 待機続行
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// エラーが存在すれば、これ以上待機する価値はなし
|
|
499
|
+
if (authorizeAction.error !== undefined) {
|
|
500
|
+
error = authorizeAction.error;
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (typeof result?.id === 'string') {
|
|
506
|
+
return result;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
throw error;
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
main()
|
|
514
|
+
.then(() => {
|
|
515
|
+
console.log('success!');
|
|
516
|
+
})
|
|
517
|
+
.catch(console.error);
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
-
// tslint:disable:no-implicit-dependencies no-console
|
|
1
|
+
// tslint:disable:no-implicit-dependencies no-console no-null-keyword
|
|
2
|
+
// import * as fs from 'fs';
|
|
2
3
|
import * as client from '../../lib/index';
|
|
4
|
+
// import * as auth from './auth/authAsAdmin';
|
|
3
5
|
import { auth } from './auth/clientCredentials';
|
|
4
6
|
|
|
5
7
|
const PROJECT_ID = String(process.env.PROJECT_ID);
|
|
6
8
|
|
|
7
9
|
async function main() {
|
|
10
|
+
// const authClient = await auth.login();
|
|
11
|
+
// await authClient.refreshAccessToken();
|
|
12
|
+
// const loginTicket = authClient.verifyIdToken({});
|
|
13
|
+
// console.log('username is', loginTicket.getUsername());
|
|
14
|
+
|
|
8
15
|
const eventService = new (await client.loadService()).Event({
|
|
9
16
|
endpoint: <string>process.env.API_ENDPOINT,
|
|
10
17
|
auth: await auth(),
|
|
18
|
+
// auth: authClient,
|
|
11
19
|
project: { id: PROJECT_ID },
|
|
12
|
-
seller: { id: '' }
|
|
20
|
+
seller: { id: '59d20831e53ebc2b4e774466' }
|
|
13
21
|
});
|
|
14
22
|
|
|
15
23
|
const event = await eventService.findById({
|
|
16
24
|
id: 'bm2bfj55o',
|
|
17
25
|
typeOf: client.factory.eventType.ScreeningEvent
|
|
18
26
|
});
|
|
19
|
-
// tslint:disable-next-line:no-null-keyword
|
|
20
27
|
console.dir(event, { depth: null });
|
|
28
|
+
// tslint:disable-next-line:non-literal-fs-path
|
|
29
|
+
// fs.writeFileSync(`${__dirname}/event2.json`, JSON.stringify(event, null, ' '));
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
main()
|
|
@@ -77,6 +77,9 @@ export declare class EventService extends Service {
|
|
|
77
77
|
};
|
|
78
78
|
onlyValid?: boolean;
|
|
79
79
|
includePotentialSpec?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* サブカタログに含まれるオファーを検索する場合、強制的にサブカタログの適用決済カード条件に変更されます
|
|
82
|
+
*/
|
|
80
83
|
priceSpecification: Pick<factory.unitPriceOffer.IPriceSpecificationSearchConditions, 'appliesToMovieTicket'>;
|
|
81
84
|
includedInDataCatalog: {
|
|
82
85
|
/**
|