idconvert/pb_hooks/credits.pb.js

98 lines
3.4 KiB
JavaScript

/// <reference path="../pb_data/types.d.ts" />
// ── Credit deduction — fires when a conversion record is created ───────────────
onRecordBeforeCreateRequest((e) => {
const userId = e.record.get('user')
const fileHash = e.record.get('file_hash')
$app.dao().runInTransaction((txDao) => {
const user = txDao.findRecordById('users', userId)
const balance = user.getInt('credits_balance')
const freeUsed = user.getBool('free_used')
// Free tier path — first conversion for this account
if (!freeUsed) {
user.set('free_used', true)
txDao.saveRecord(user)
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
txRecord.set('user', userId)
txRecord.set('type', 'free')
txRecord.set('credits', 0)
txRecord.set('balance_after', balance)
txRecord.set('file_hash', fileHash)
txDao.saveRecord(txRecord)
return // allow conversion record to be created
}
// Paid path — check balance
if (balance < 1) {
throw new Error('INSUFFICIENT_CREDITS')
}
const newBalance = balance - 1
user.set('credits_balance', newBalance)
txDao.saveRecord(user)
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
txRecord.set('user', userId)
txRecord.set('type', 'conversion')
txRecord.set('credits', -1)
txRecord.set('balance_after', newBalance)
txRecord.set('file_hash', fileHash)
txDao.saveRecord(txRecord)
})
}, 'conversions')
// ── Credit refund — fires when a conversion is marked failed ─────────────────
onRecordAfterUpdateRequest((e) => {
if (e.record.get('status') !== 'failed') return
const userId = e.record.get('user')
$app.dao().runInTransaction((txDao) => {
const user = txDao.findRecordById('users', userId)
// Only refund paid conversions — free conversions cost nothing
if (!user.getBool('free_used')) return
const newBalance = user.getInt('credits_balance') + 1
user.set('credits_balance', newBalance)
txDao.saveRecord(user)
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
txRecord.set('user', userId)
txRecord.set('type', 'refund')
txRecord.set('credits', +1)
txRecord.set('balance_after', newBalance)
txDao.saveRecord(txRecord)
})
}, 'conversions')
// ── Credit top-up — fires when a purchase record is created (from Stripe webhook) ──
onRecordBeforeCreateRequest((e) => {
const userId = e.record.get('user')
const credits = e.record.getInt('credits')
const stripeId = e.record.get('stripe_id')
$app.dao().runInTransaction((txDao) => {
const user = txDao.findRecordById('users', userId)
const newBalance = user.getInt('credits_balance') + credits
user.set('credits_balance', newBalance)
txDao.saveRecord(user)
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
txRecord.set('user', userId)
txRecord.set('type', 'purchase')
txRecord.set('credits', credits)
txRecord.set('balance_after', newBalance)
txRecord.set('stripe_id', stripeId)
txDao.saveRecord(txRecord)
})
}, 'purchases')