212 lines
5.8 KiB
JavaScript
212 lines
5.8 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.fullPayProjection = void 0;
|
||
exports.payNotify = payNotify;
|
||
exports.refundNotify = refundNotify;
|
||
exports.refreshPayState = refreshPayState;
|
||
const tslib_1 = require("tslib");
|
||
const payClazz_1 = require("./payClazz");
|
||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
||
exports.fullPayProjection = {
|
||
id: 1,
|
||
applicationId: 1,
|
||
price: 1,
|
||
meta: 1,
|
||
iState: 1,
|
||
depositId: 1,
|
||
deposit: {
|
||
id: 1,
|
||
price: 1,
|
||
iState: 1,
|
||
accountId: 1,
|
||
},
|
||
entity: 1,
|
||
entityId: 1,
|
||
paid: 1,
|
||
refunded: 1,
|
||
timeoutAt: 1,
|
||
forbidRefundAt: 1,
|
||
orderId: 1,
|
||
order: {
|
||
id: 1,
|
||
title: 1,
|
||
desc: 1,
|
||
},
|
||
};
|
||
async function payNotify(context, body, payId, headers) {
|
||
const [pay] = await context.select('pay', {
|
||
data: {
|
||
id: 1,
|
||
price: 1,
|
||
iState: 1,
|
||
entity: 1,
|
||
entityId: 1,
|
||
meta: 1,
|
||
applicationId: 1,
|
||
},
|
||
filter: {
|
||
id: payId,
|
||
}
|
||
}, { blockTrigger: true });
|
||
if (!pay) {
|
||
console.error('接受到无效的payId', payId);
|
||
return;
|
||
}
|
||
const { applicationId, entity, entityId, price } = pay;
|
||
const payClazz = await (0, payClazz_1.getPayClazz)(entity, entityId, context);
|
||
const { payId: payId2, iState, extra } = await payClazz.decodePayNotification({
|
||
headers,
|
||
}, body);
|
||
(0, assert_1.default)(payId2 === payId);
|
||
if (iState !== pay.iState) {
|
||
let action = 'close';
|
||
const updateData = {};
|
||
switch (iState) {
|
||
case 'closed': {
|
||
// action = 'close';
|
||
break;
|
||
}
|
||
case 'paid': {
|
||
action = 'succeedPaying';
|
||
updateData.paid = price;
|
||
if (extra) {
|
||
Object.assign(updateData, extra);
|
||
}
|
||
break;
|
||
}
|
||
default: {
|
||
(0, assert_1.default)(false);
|
||
}
|
||
}
|
||
await context.operate('pay', {
|
||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||
action,
|
||
data: updateData,
|
||
filter: {
|
||
id: payId,
|
||
}
|
||
}, {});
|
||
}
|
||
return;
|
||
}
|
||
async function refundNotify(context, body, refundId, headers) {
|
||
const [refund] = await context.select('refund', {
|
||
data: {
|
||
id: 1,
|
||
price: 1,
|
||
iState: 1,
|
||
pay: {
|
||
entity: 1,
|
||
entityId: 1,
|
||
}
|
||
},
|
||
filter: {
|
||
id: refundId,
|
||
}
|
||
}, {});
|
||
if (!refund) {
|
||
console.error('接受到无效的refundId', refundId);
|
||
return;
|
||
}
|
||
const { entity, entityId } = refund.pay;
|
||
const payClazz = await (0, payClazz_1.getPayClazz)(entity, entityId, context);
|
||
const { refundId: refundId2, extra, iState, } = await payClazz.decodeRefundNotification({ headers }, body);
|
||
(0, assert_1.default)(refundId2 === refundId);
|
||
if (iState !== refund.iState) {
|
||
let action = 'succeed';
|
||
const updateData = {};
|
||
switch (iState) {
|
||
case 'successful': {
|
||
// action = 'close';
|
||
break;
|
||
}
|
||
case 'failed': {
|
||
action = 'fail';
|
||
break;
|
||
}
|
||
default: {
|
||
(0, assert_1.default)(false);
|
||
}
|
||
}
|
||
if (extra) {
|
||
Object.assign(updateData, extra);
|
||
}
|
||
await context.operate('refund', {
|
||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||
action,
|
||
data: updateData,
|
||
filter: {
|
||
id: refundId,
|
||
}
|
||
}, {});
|
||
}
|
||
}
|
||
/**
|
||
* 刷新paying状态的pay的真实支付状态
|
||
* @param pay
|
||
* @param context
|
||
* @returns
|
||
*/
|
||
async function refreshPayState(pay, context) {
|
||
let pay2 = pay;
|
||
if (!pay2.entity || !pay2.entityId || !pay2.timeoutAt || !pay2.price || !pay2.iState) {
|
||
const pays = await context.select('pay', {
|
||
data: {
|
||
id: 1,
|
||
entity: 1,
|
||
entityId: 1,
|
||
price: 1,
|
||
iState: 1,
|
||
},
|
||
filter: {
|
||
id: pay.id,
|
||
}
|
||
}, {
|
||
blockTrigger: true,
|
||
forUpdate: true,
|
||
});
|
||
pay2 = pays[0];
|
||
}
|
||
const { entity, entityId, timeoutAt, price } = pay2;
|
||
const clazz = await (0, payClazz_1.getPayClazz)(entity, entityId, context);
|
||
const [iState, updateData] = await clazz.getState(pay);
|
||
if (iState !== pay.iState) {
|
||
let action = 'close';
|
||
switch (iState) {
|
||
case 'closed': {
|
||
// action = 'close';
|
||
break;
|
||
}
|
||
case 'paid': {
|
||
action = 'succeedPaying';
|
||
updateData.paid = price;
|
||
break;
|
||
}
|
||
default: {
|
||
(0, assert_1.default)(false);
|
||
}
|
||
}
|
||
return await context.operate('pay', {
|
||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||
action,
|
||
data: updateData,
|
||
filter: {
|
||
id: pay.id,
|
||
}
|
||
}, {});
|
||
}
|
||
else if (iState === 'paying' && timeoutAt < Date.now()) {
|
||
// 尝试关闭订单
|
||
// 理论上用户可能在上一个getState和这个close之间支付完成,此时关闭失败,下一个Watcher到来时就能处理成功了
|
||
return await context.operate('pay', {
|
||
id: await (0, uuid_1.generateNewIdAsync)(),
|
||
action: 'close',
|
||
data: updateData,
|
||
filter: {
|
||
id: pay.id,
|
||
}
|
||
}, {});
|
||
}
|
||
}
|