Skip to content

Commit

Permalink
DASH-150 add bitpay handle to payments job
Browse files Browse the repository at this point in the history
  • Loading branch information
orkhan-huseyn committed Feb 7, 2023
1 parent 2b9cf60 commit 78c588b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 8 deletions.
5 changes: 5 additions & 0 deletions server/src/external/payment-processor/bitpay.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ class BitPay extends PaymentProcessor {
bitPayInvoice.currency,
);
}

async retrieveIntent(id) {
const bitPayClient = await this.getBitPayClient();
return await bitPayClient.GetInvoice(id);
}
}

export default new BitPay();
54 changes: 46 additions & 8 deletions server/src/jobs/payments.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,45 @@
import { Op } from 'sequelize';

import CommonJob from './job.mjs';

import Stripe from '../external/payment-processor/stripe.mjs';
import Bitpay from '../external/payment-processor/bitpay.mjs';

import logger from '../logger.mjs';

import { Order, Payment, OrderItem, OrderItemStatus } from '../models';

// https://stripe.com/docs/payments/intents#intent-statuses
const STRIPE_INTENT_SUCCESS = 'succeeded';
// https://bitpay.com/api/#rest-api-resources-invoices-resource
const BITPAY_PAYMENT_SUCCESS = 'paid';

class PaymentsJob extends CommonJob {
async fetchIntentFromAPI(id, processor) {
let intent;
if (processor === Payment.PROCESSOR.STRIPE) {
intent = await Stripe.retrieveIntent(id);
} else if (processor === Payment.PROCESSOR.BITPAY) {
intent = await Bitpay.retrieveIntent(id);
}
return intent;
}

getSuccessStatusByProcessor(processor) {
if (processor === Payment.PROCESSOR.STRIPE) {
return STRIPE_INTENT_SUCCESS;
}
if (processor === Payment.PROCESSOR.BITPAY) {
return BITPAY_PAYMENT_SUCCESS;
}
}

testPaymentSuccess(entry) {
const [processor, status] = entry;
const successStatus = this.getSuccessStatusByProcessor(processor);
return status === successStatus;
}

async execute() {
const orders = await Order.findAll({
where: {
Expand All @@ -19,11 +49,15 @@ class PaymentsJob extends CommonJob {
});

const t = await Order.sequelize.transaction();

try {
for (const order of orders) {
const payments = await order.getPayments({
where: { processor: Payment.PROCESSOR.STRIPE },
where: {
[Op.or]: [
{ processor: Payment.PROCESSOR.STRIPE },
{ processor: Payment.PROCESSOR.BITPAY },
],
},
});
const paymentStatuses = [];
for (const payment of payments) {
Expand All @@ -35,9 +69,9 @@ class PaymentsJob extends CommonJob {
});

const intentId = payment.externalId;
const intent = await Stripe.retrieveIntent(intentId);
paymentStatuses.push(intent.status);
if (intent.status === STRIPE_INTENT_SUCCESS) {
const intent = this.fetchIntentFromAPI(intentId, payment.processor);
paymentStatuses.push([payment.processor, intent.status]);
if (intent.status === this.getSuccessStatusByProcessor(payment.processor)) {
await payment.update(
{ status: Payment.STATUS.COMPLETED },
{ transaction: t },
Expand All @@ -55,11 +89,15 @@ class PaymentsJob extends CommonJob {
}
}

const allSucceeded = paymentStatuses.some(
status => status === STRIPE_INTENT_SUCCESS,
);
const allSucceeded = paymentStatuses.every(this.testPaymentSuccess);
const someSucceeded = paymentStatuses.some(this.testPaymentSuccess);
if (allSucceeded) {
await order.update({ status: Order.STATUS.SUCCESS }, { transaction: t });
} else if (someSucceeded) {
await order.update(
{ status: Order.STATUS.PARTIALLY_SUCCESS },
{ transaction: t },
);
} else {
await order.update({ status: Order.STATUS.FAILED }, { transaction: t });
}
Expand Down

0 comments on commit 78c588b

Please sign in to comment.