Last active
December 7, 2023 08:51
-
-
Save ccurtin/27b0812351f6bface5a8ab46afeeed7d to your computer and use it in GitHub Desktop.
Braintree API / node How to upgrade a MONTHLY subscription to YEARLY subscription. Rough example. Braintree does NOT automatically prorate user's monthly balance onto the yearly subscription so MUST refund the user's latest Transaction before cancelling current subscription and creating a new subscription.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1) Get the customer... required the get the payment method token | |
await braintreeGateway.customer.find( | |
billing_customer_id, | |
async (err, customer) => { | |
await braintreeGateway.subscription.find( | |
subscriptionId, | |
async (err, subscription) => { | |
if (err) { | |
res.status(400).json({ | |
error_message: err && err.code | |
? `ERROR (braintree code ${err.code}) : ${err.message}` | |
: 'Unable to find subscription.' | |
}) | |
} | |
const lastTransactionId = subscription.transactions[0].id | |
const lastTransactionAmount = Number(subscription.transactions[0].amount) | |
const billingPeriodStartDate = subscription.billingPeriodStartDate | |
const billingPeriodEndDate = subscription.billingPeriodEndDate | |
const paidForDays = daysPassedSince(billingPeriodStartDate) | |
const refundAmount = lastTransactionAmount - (lastTransactionAmount / (daysPassedSince(billingPeriodStartDate, billingPeriodEndDate)) * paidForDays).toFixed(2) | |
// 2) Prorate the rest of the month's subscription fee back to the user | |
await braintreeGateway.transaction.refund( | |
lastTransactionId, String(refundAmount), | |
async (err, refund) => { | |
if (err) { | |
res.status(400).json({ | |
error_message: err && err.code | |
? `ERROR (braintree code ${err.code}) : ${err.message}` | |
: 'Unable to upgrade to new plan. Refund failure.' | |
}) | |
} else { | |
// 3) Cancel the current subscription. Must be canceled since billing periods are different | |
await braintreeGateway.subscription.cancel( | |
subscriptionId, | |
async (err, result) => { | |
if (err) { | |
res.status(400).json({ | |
error_message: err && err.code | |
? `ERROR (braintree code ${err.code}) : ${err.message}` | |
: 'Unable to upgrade to new plan. Cancellation failure.' | |
}) | |
} | |
// 4) Create the new/yearly subscription | |
await braintreeGateway.subscription.create( | |
{ | |
paymentMethodToken: customer.paymentMethods[0].token, | |
planId: new_plan_id | |
}, | |
async (err, subscription) => { | |
if (err) { | |
res.status(400).json({ | |
error_message: err && err.code | |
? `ERROR (braintree code ${err.code}) : ${err.message}` | |
: 'Unable to upgrade to new plan. Subscription create failure.'}) | |
} | |
// set the new subscription_id in the database | |
await updateSubscriptionId(billing_customer_id, subscription.subscription.id ) | |
// updates `user.upgrade_status` to 'upgraded' and `user.subscription_type` to 'yearly' | |
await setUserUpgradeStatus(req.user.id, 'upgraded', 'yearly') | |
res.json({subscription, refund, invoice: false}) | |
} | |
) | |
} | |
) | |
} | |
} | |
) | |
} | |
) | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment