@lomray/microservice-payment-stripe
Version:
Stripe payment microservice based on NodeJS & inverted json.
164 lines (160 loc) • 7.52 kB
JavaScript
'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 card$1 = require('../entities/card.js');
var customer = require('../entities/customer.js');
var messages = require('../helpers/validators/messages.js');
var card = require('../repositories/card.js');
var stripe = require('./payment-gateway/stripe.js');
/**
* Card service
* @TODO: Add support if needed when card will be used as the external account in the connect account
* NOTE: Card handling as the payment method
*/
class Card {
/**
* Handle create
* @description NOTES:
* 1. Card should be created from setup intent succeed
* 2. Should be called after insert
*/
static handleAfterInsert(entity, manager) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const paymentMethodId = card.extractPaymentMethodId(entity);
if (!paymentMethodId) {
/**
* External account card (card attached as payout method for connect account)
*/
void microserviceNodejsLib.Microservice.eventPublish(Event.CardCreated, entity);
return;
}
const cardRepository = manager.getRepository(card$1);
const customerRepository = manager.getRepository(customer);
/**
* Get attached cards count as the payment method
*/
const cardsCount = yield cardRepository
.createQueryBuilder('card')
.where('card.userId = :userId', { userId: entity.userId })
// Select cards that attached to connect account (have payment method id)
.andWhere(`(card.params ->> 'paymentMethodId' IS NOT NULL OR card."paymentMethodId" IS NOT NULL)`)
.andWhere('card.isDefault = :isDefault', { isDefault: true })
.getCount();
// If default card already exist - publish event
if (cardsCount >= 1) {
void microserviceNodejsLib.Microservice.eventPublish(Event.CardCreated, entity);
return;
}
// If 1 (current card) with the required params for payment method
const customer$1 = yield customerRepository.findOne({ userId: entity.userId });
if (!customer$1) {
throw new microserviceNodejsLib.BaseException({
status: 500,
message: messages.getNotFoundMessage('Customer'),
payload: {
userId: entity.userId,
},
});
}
const service = yield stripe.init(manager);
const isSet = yield service.setDefaultCustomerPaymentMethod(customer$1.customerId, paymentMethodId);
if (!isSet) {
throw new microserviceNodejsLib.BaseException({
status: 500,
message: 'Failed to set card as the default payment method for customer.',
});
}
entity.isDefault = true;
yield cardRepository.save(entity, { listeners: false });
void microserviceNodejsLib.Microservice.eventPublish(Event.CardCreated, entity);
});
}
/**
* Handle update stripe card and card entities default payment method status
* @TODO: Handle external account card data updated
*/
static handleUpdate(databaseEntity, entity, manager) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const paymentMethodId = card.extractPaymentMethodId(entity);
/**
* If card isn't payment method
*/
if (!paymentMethodId || databaseEntity.isDefault === entity.isDefault) {
return;
}
if (!entity.isDefault) {
throw new microserviceNodejsLib.BaseException({ status: 500, message: "Card can't be set manually to default" });
}
const cardRepository = manager.getRepository(card$1);
const customerRepository = manager.getRepository(customer);
const service = yield stripe.init();
const { userId } = entity;
// Get all customer related card
const cards = yield cardRepository.find({
userId,
});
if (!cards.length) {
throw new microserviceNodejsLib.BaseException({ status: 500, message: "Cards aren't found." });
}
const customer$1 = yield customerRepository.findOne({ userId });
if (!customer$1) {
throw new microserviceNodejsLib.BaseException({ status: 500, message: messages.getNotFoundMessage('Customer') });
}
const isSet = yield service.setDefaultCustomerPaymentMethod(customer$1.customerId, paymentMethodId);
if (!isSet) {
throw new microserviceNodejsLib.BaseException({
status: 500,
message: 'Failed to set card as the default payment method for customer',
});
}
/**
* Update cards default statuses on change default card for charge
*/
yield Promise.all(cards.map((card$1) => {
card$1.isDefault = card.extractPaymentMethodId(card$1) === paymentMethodId;
return cardRepository.save(card$1, { listeners: false });
}));
/**
* Check if customer has default payment method
*/
if (customer$1.params.hasDefaultPaymentMethod && paymentMethodId) {
return;
}
customer$1.params.hasDefaultPaymentMethod = Boolean(paymentMethodId);
yield customerRepository.save(customer$1);
void microserviceNodejsLib.Microservice.eventPublish(Event.CardUpdated, entity);
});
}
/**
* Handle remove card if it's payment method
*/
static handleRemove(databaseEntity, manager, { data: { isFromWebhook } }) {
return tslib.__awaiter(this, void 0, void 0, function* () {
const service = yield stripe.init();
// If card was removed from Stripe event(e.g. dashboard)
if (isFromWebhook) {
void microserviceNodejsLib.Microservice.eventPublish(Event.CardRemoved, databaseEntity);
return;
}
if (databaseEntity.isDefault) {
throw new microserviceNodejsLib.BaseException({ status: 400, message: "Default card can't be removed." });
}
/**
* Handle setup intent card (card have payment method reference), NOT external account
*/
const paymentMethodId = card.extractPaymentMethodId(databaseEntity);
if (paymentMethodId) {
const isRemoved = yield service.removeCustomerPaymentMethod(paymentMethodId);
if (!isRemoved) {
throw new microserviceNodejsLib.BaseException({
status: 500,
message: 'Failed to remove card as the payment method.',
});
}
}
void microserviceNodejsLib.Microservice.eventPublish(Event.CardRemoved, databaseEntity);
});
}
}
module.exports = Card;