Skip to content

Instantly share code, notes, and snippets.

@ismummy
Created July 2, 2021 12:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ismummy/36553daa5d274ba97de1f3fd607aebc8 to your computer and use it in GitHub Desktop.
Save ismummy/36553daa5d274ba97de1f3fd607aebc8 to your computer and use it in GitHub Desktop.
Flutterwave Recurring Charge
//first check if card data exist in the transaction verification response then save the card token in db
static saveCardToken = async (verificationData, Customer) => {
if (verificationData) {
const paymentType = verificationData.paymenttype
if (paymentType === "card" || paymentType === "CARD") {
if (verificationData.card) {
const paymentCard = verificationData.card
const token = paymentCard.life_time_token
? paymentCard.life_time_token
: paymentCard.card_tokens
? paymentCard.card_tokens[0].embedtoken
: null
const newCardData = {
customerId: Customer.id,
token,
cardBin: paymentCard.cardBIN,
lastFour: paymentCard.last4digits,
cardType: paymentCard.type,
expiryMonth: paymentCard.expirymonth,
expiryYear: paymentCard.expiryyear,
brand: paymentCard.brand,
}
await PaymentCardModel.addNewCard(newCardData, (response) => {
})
console.log("Token saved")
}
}
}
}
//Save card method checks if the caard already saved and also check if user has default card set
PaymentCard.addNewCard = (data, callback) => {
if(!data.customerId || !data.token) return callback({success: false, message: 'Please provide required details'});
try {
var { customerId, token } = data;
//check if card already exists
PaymentCard.findOne({
where: { customerId, token }
}).then(card => {
if(card) return callback({success: false, message: 'Card already exists for this customer'});
//check if customer already has a card on the system
PaymentCard.count({where: {customerId}}).then(totalCards => {
data['isDefault'] = (totalCards < 1) ? true : false;
PaymentCard.create(data).then(newCard => {
return callback({success: true, message: 'Payment card successfully added'});
})
});
});
} catch (error) {
return callback({success: false, message: 'Error occurred'});
}
}
//charge customer with card on renewal date
//process subscriptions whose renewal or near
static CronChargeByNextBillingDate = async () => {
console.log('Running charge by next billing date job at ' + new Date())
const today = moment().startOf("day");
const tomorrow = moment().add(1, "days").endOf("day");
const subscriptions = await SubscriptionModel.findAll({
where: {
isActive: true,
status: "active",
nextBillingDate: {$ne: null, $lte: tomorrow, $gte: today},
},
include: [
{
model: models.Customer,
}
],
})
if (!subscriptions || subscriptions.length < 1)
return "Found no subscriptions at this time"
for (const subscription of subscriptions) {
const {Customer, nextBillingDate, amount} = subscription;
const customerId = Customer.id;
const customerEmail = Customer.email;
const newNextBillingDate = moment(nextBillingDate)
.add(1, "month")
.subtract(1, "day");
//find customer's default card
await PaymentCardModel.findCustomersDefaultCard(customerId, async (result) => {
//if customer does not have a card, send a message, and update transaction nextcrontime
if (result.success) {
const paymentReference = General.GeneratePaymentReference();
const chargeData = {
token: result.card.token,
txRef: paymentReference,
amount: amount,
email: customerEmail,
};
await RavePay.ChargeToken(chargeData, async (chargeResponse) => {
if (chargeResponse.success) {
//save the payment details
/perform other logic here
}
});
}
}
);
}
};
@ismummy
Copy link
Author

ismummy commented Jul 5, 2021

getNextScheduleDate = (interval, startDate) => {

        let durationFormat = null
        if (interval === "daily") {
            durationFormat = {"days": 1}
        } else if (interval === "weekly") {
            durationFormat = {"weeks": 1}
        } else if (interval === "bi-weekly") {
            durationFormat = {"days": 3}
        } else if (interval === "monthly") {
            durationFormat = {"months": 1}
        } else if (interval === "bi-monthly") {
            durationFormat = {"days": 14}
        } else if (interval === "one-time") {
            durationFormat = {"seconds": 10}
        }

        const duration = moment.duration(durationFormat)
        const addDuration = moment(startDate).add(duration)
        console.log("NEXT SCHEDULE DATE", startDate, duration.toString(), addDuration.toString())
        return addDuration
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment