UNPKG

@lomray/microservice-payment-stripe

Version:

Stripe payment microservice based on NodeJS & inverted json.

117 lines (113 loc) 4.61 kB
'use strict'; 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;