@lomray/microservice-payment-stripe
Version:
Stripe payment microservice based on NodeJS & inverted json.
117 lines (113 loc) • 4.61 kB
JavaScript
;
var tslib = require('tslib');
var microserviceNodejsLib = require('@lomray/microservice-nodejs-lib');
var Event = require('@lomray/microservices-client-api/constants/events/payment-stripe');
var chargeRefundStatus = require('../constants/charge-refund-status.js');
var transactionStatus = require('../constants/transaction-status.js');
var transactionType = require('../constants/transaction-type.js');
var dispute = require('../entities/dispute.js');
var transaction = require('../entities/transaction.js');
var stripe = require('./payment-gateway/stripe.js');
/**
* Transaction service
*/
class Transaction {
/**
* Handle after create
*/
static handleAfterCreate(entity) {
return tslib.__awaiter(this, void 0, void 0, function* () {
yield microserviceNodejsLib.Microservice.eventPublish(Event.TransactionCreated, entity);
});
}
/**
* Handle after update
*/
static handleAfterUpdate(entity, databaseEntity, manager, updateColumns) {
return tslib.__awaiter(this, void 0, void 0, function* () {
yield this.syncStats(entity, manager);
if (this.notSucceededTransactionStatuses.includes(entity.status)) {
yield microserviceNodejsLib.Microservice.eventPublish(Event.TransactionUpdated, entity);
return;
}
const isChargeUpdated = updateColumns.some(({ propertyName }) => propertyName === 'chargeId');
// Attach required to transactions Stripe references and amount
if (isChargeUpdated && entity.chargeId && !databaseEntity.chargeId) {
yield (yield stripe.init(manager)).attachToTransactionsChargeRefs(entity.chargeId);
}
yield microserviceNodejsLib.Microservice.eventPublish(Event.TransactionUpdated, entity);
});
}
/**
* Update transaction stats
* @description Sync stats that can be missed due webhook events
*/
static syncStats({ type, amount, transactionId, params: { refundedTransactionAmount } }, manager) {
return tslib.__awaiter(this, void 0, void 0, function* () {
// Credit transaction contain total transaction amount
if (type !== transactionType.CREDIT) {
return;
}
const transactionRepository = manager.getRepository(transaction);
const disputeRepository = manager.getRepository(dispute);
/**
* Get transactions
*/
const [transactions, disputeCount] = yield Promise.all([
transactionRepository.find({
where: {
transactionId,
},
}),
disputeRepository.count({ where: { transactionId } }),
]);
const isTransactionDisputed = Boolean(disputeCount);
if (!transactions.length) {
return;
}
const updatedChargeRefundStatus = this.getChargeRefundStatus(amount, refundedTransactionAmount);
let isUpdated = false;
let isListeners = false;
transactions.forEach((transaction) => {
// Sync charge refund status
if (transaction.chargeRefundStatus !== updatedChargeRefundStatus) {
transaction.chargeRefundStatus = updatedChargeRefundStatus;
isUpdated = true;
}
// Sync dispute status
if (!isTransactionDisputed || transaction.isDisputed === isTransactionDisputed) {
return;
}
transaction.isDisputed = true;
isUpdated = true;
isListeners = true;
});
if (!isUpdated) {
return;
}
yield transactionRepository.save(transactions, { listeners: isListeners });
});
}
/**
* Returns charge refund status
*/
static getChargeRefundStatus(amount, refundedTransactionAmount) {
if (refundedTransactionAmount === amount) {
return chargeRefundStatus.FULL_REFUND;
}
if (refundedTransactionAmount > 0) {
return chargeRefundStatus.PARTIAL_REFUND;
}
return chargeRefundStatus.NO_REFUND;
}
}
/**
* Not succeeded transaction statuses
*/
Transaction.notSucceededTransactionStatuses = [
transactionStatus.INITIAL,
transactionStatus.IN_PROCESS,
transactionStatus.ERROR,
transactionStatus.EXPIRED,
];
module.exports = Transaction;