Skip to content

Commit 6dd9f68

Browse files
committed
fix many paypal issues, paypal sucks
1 parent ebf25b0 commit 6dd9f68

6 files changed

Lines changed: 178 additions & 124 deletions

File tree

Synergism.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4962,6 +4962,11 @@ form input:hover {
49624962
text-align: center;
49634963
}
49644964

4965+
.subscriptionContainer > div > div.checkout-paypal {
4966+
width: 76%;
4967+
margin: 0 auto;
4968+
}
4969+
49654970
#pseudoCoins > #productContainer > section > * > .pseudoCoinImage {
49664971
margin-top: 8px;
49674972
}

src/Login.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,14 @@ const DIAMOND_SMITH_MESSIAH = '1311165096378105906'
6969
let ws: WebSocket | undefined
7070
let loggedIn = false
7171
let tips = 0
72+
let subscription: SubscriptionMetadata = null
7273

7374
const cloudSaves: Save[] = []
7475

7576
export const isLoggedIn = () => loggedIn
7677
export const getTips = () => tips
7778
export const setTips = (newTips: number) => tips = newTips
79+
export const getSubMetadata = () => subscription
7880

7981
export const allDurableConsumables: Record<PseudoCoinConsumableNames, Consumable> = {
8082
HAPPY_HOUR_BELL: {
@@ -201,14 +203,19 @@ interface BonusTypes {
201203
quarks: number
202204
}
203205

206+
type SubscriptionMetadata = {
207+
provider: 'paypal' | 'stripe' | 'patreon'
208+
tier: number
209+
} | null
210+
204211
interface SynergismUserAPIResponse<T extends keyof AccountMetadata> {
205212
personalBonus: number
206213
globalBonus: number
207214
member: AccountMetadata[T]
208215
accountType: T
209216
bonus: BonusTypes
210-
subscriptionTier: number
211217
error?: unknown
218+
subscription: SubscriptionMetadata
212219
}
213220

214221
const isDiscordAccount = (
@@ -244,28 +251,29 @@ export async function handleLogin () {
244251
personalBonus: 0,
245252
accountType: 'none',
246253
bonus: { quarks: 0 },
247-
subscriptionTier: 0
254+
subscription: null
248255
} satisfies SynergismUserAPIResponse<'none'>
249256
),
250257
{ status: 401 }
251258
)
252259
)
253260

254261
const account = await response.json() as SynergismUserAPIResponse<keyof AccountMetadata>
255-
const { globalBonus, personalBonus, subscriptionTier } = account
262+
const { globalBonus, personalBonus, subscription: sub } = account
256263

257264
setQuarkBonus(personalBonus, globalBonus)
258265
setInterval(() => refreshQuarkBonus(), 1000 * 60 * 15)
259266
player.worlds = new QuarkHandler(Number(player.worlds))
260267
loggedIn = hasAccount(account)
268+
subscription = sub
261269

262270
currentBonus.textContent = i18next.t('settings.quarkBonusSimple', { globalBonus })
263271

264272
// biome-ignore lint/suspicious/noConfusingLabels: it's not confusing or suspicious
265273
generateSubtab: {
266274
if (location.hostname !== 'synergism.cc') {
267-
// TODO: better error, make link clickable, etc.
268-
subtabElement.textContent = 'Login is not available here, go to https://synergism.cc instead!'
275+
subtabElement.innerHTML =
276+
'Login is not available here, go to <a href="https://synergism.cc">https://synergism.cc</a> instead!'
269277
} else if (hasAccount(account)) {
270278
if (Object.keys(account.member).length === 0) {
271279
subtabElement.innerHTML = `You are logged in, but your profile couldn't be retrieved from Discord or Patreon.`
@@ -298,10 +306,10 @@ export async function handleLogin () {
298306
const boosted = discord && (Boolean(account.member?.premium_since) || account.member?.roles.includes(BOOSTER))
299307
// It is possible for someone to have the roles through the Patreon integration with Discord, yet not have their
300308
// patreon linked to their Synergism (Discord/email) account.
301-
const hasTier1 = subscriptionTier === 1 || (discord && account.member.roles?.includes(TRANSCENDED_BALLER))
302-
const hasTier2 = subscriptionTier === 2 || (discord && account.member.roles?.includes(REINCARNATED_BALLER))
303-
const hasTier3 = subscriptionTier === 3 || (discord && account.member.roles?.includes(ASCENDED_BALLER))
304-
const hasTier4 = subscriptionTier === 4 || (discord && account.member.roles?.includes(OMEGA_BALLER))
309+
const hasTier1 = sub?.tier === 1 || (discord && account.member.roles?.includes(TRANSCENDED_BALLER))
310+
const hasTier2 = sub?.tier === 2 || (discord && account.member.roles?.includes(REINCARNATED_BALLER))
311+
const hasTier3 = sub?.tier === 3 || (discord && account.member.roles?.includes(ASCENDED_BALLER))
312+
const hasTier4 = sub?.tier === 4 || (discord && account.member.roles?.includes(OMEGA_BALLER))
305313

306314
const checkMark = (n: number) => {
307315
return `<span style="color: lime">[✔] {+${n}%}</span>`

src/mock/browser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ export const worker = setupWorker(
12091209
bonus: {
12101210
quarkBonus: 0
12111211
},
1212-
subscriptionTier: 0
1212+
subscription: null
12131213
})
12141214
}),
12151215
...GETHandlers,

src/purchases/CheckoutTab.ts

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Alert, Confirm, Notification } from '../UpdateHTML'
44
import { memoize } from '../Utility'
55
import { products, subscriptionProducts } from './CartTab'
66
import { addToCart, clearCart, getPrice, getProductsInCart, getQuantity, removeFromCart } from './CartUtil'
7+
import { initializePayPal_Subscription } from './SubscriptionsSubtab'
78
import { updatePseudoCoins } from './UpgradesSubtab'
89

910
const tab = document.querySelector<HTMLElement>('#pseudoCoins > #cartContainer')!
@@ -98,7 +99,7 @@ export const initializeCheckoutTab = memoize(() => {
9899
checkoutStripe?.addEventListener('click', submitCheckout)
99100
checkoutNowPayments?.addEventListener('click', submitCheckout)
100101

101-
initializePayPal('#checkout-paypal')
102+
initializePayPal_OneTime('#checkout-paypal')
102103
})
103104

104105
function addItem (e: MouseEvent) {
@@ -177,55 +178,59 @@ const updateTotalPriceInCart = () => {
177178
totalCost!.textContent = `${formatter.format(getPrice() / 100)} USD`
178179
}
179180

180-
async function initializePayPal (selector: string | HTMLElement) {
181-
try {
182-
const paypal = await loadScript({
183-
clientId: 'AS1HYTVcH3Kqt7IVgx7DkjgG8lPMZ5kyPWamSBNEowJ-AJPpANNTJKkB_mF0C4NmQxFuWQ9azGbqH2Gr',
184-
disableFunding: ['paylater', 'credit', 'card', 'venmo']
185-
})
186-
187-
paypal?.Buttons?.({
188-
style: {
189-
shape: 'rect',
190-
layout: 'vertical',
191-
color: 'gold',
192-
label: 'paypal'
193-
},
194-
195-
async createOrder () {
196-
const fd = new FormData()
197-
198-
for (const product of getProductsInCart()) {
199-
if (product.quantity > 0 && product.subscription) {
200-
throw new TypeError('skipping')
201-
}
202-
203-
fd.set(product.id, `${product.quantity}`)
181+
/**
182+
* https://stackoverflow.com/a/69024269
183+
*/
184+
async function initializePayPal_OneTime (selector: string | HTMLElement) {
185+
const paypal = await loadScript({
186+
clientId: 'AS1HYTVcH3Kqt7IVgx7DkjgG8lPMZ5kyPWamSBNEowJ-AJPpANNTJKkB_mF0C4NmQxFuWQ9azGbqH2Gr',
187+
disableFunding: ['paylater', 'credit', 'card', 'venmo'],
188+
dataNamespace: 'paypal_one_time'
189+
})
190+
191+
paypal?.Buttons?.({
192+
style: {
193+
shape: 'rect',
194+
layout: 'vertical',
195+
color: 'gold',
196+
label: 'paypal'
197+
},
198+
199+
async createOrder () {
200+
const fd = new FormData()
201+
202+
for (const product of getProductsInCart()) {
203+
if (product.quantity > 0 && product.subscription) {
204+
throw new TypeError('skipping')
204205
}
205206

206-
fd.set('tosAgree', radioTOSAgree.checked ? 'on' : 'off')
207-
const url = 'https://synergism.cc/paypal/orders/create'
207+
fd.set(product.id, `${product.quantity}`)
208+
}
208209

209-
const response = await fetch(url, {
210-
method: 'POST',
211-
body: fd
212-
})
210+
fd.set('tosAgree', radioTOSAgree.checked ? 'on' : 'off')
211+
const url = 'https://synergism.cc/paypal/orders/create'
213212

214-
const orderData = await response.json()
213+
const response = await fetch(url, {
214+
method: 'POST',
215+
body: fd
216+
})
215217

216-
if (orderData.id) {
217-
return orderData.id
218-
}
218+
const orderData = await response.json()
219219

220-
const errorDetail = orderData?.details?.[0]
221-
const errorMessage = errorDetail
222-
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
223-
: JSON.stringify(orderData)
220+
if (orderData.id) {
221+
return orderData.id
222+
}
223+
224+
const errorDetail = orderData?.details?.[0]
225+
const errorMessage = errorDetail
226+
? `${errorDetail.issue} ${errorDetail.description} (${orderData.debug_id})`
227+
: JSON.stringify(orderData)
224228

225-
throw new Error(errorMessage)
226-
},
229+
throw new Error(errorMessage)
230+
},
227231

228-
async onApprove (data, actions) {
232+
async onApprove (data, actions) {
233+
try {
229234
const url = `https://synergism.cc/paypal/orders/${data.orderID}/capture`
230235

231236
const response = await fetch(url, { method: 'POST' })
@@ -240,9 +245,7 @@ async function initializePayPal (selector: string | HTMLElement) {
240245
return actions.restart()
241246
} else if (errorDetail) {
242247
// (2) Other non-recoverable errors -> Show a failure message
243-
throw new Error(
244-
`${errorDetail.description} (${orderData.debug_id})`
245-
)
248+
throw new Error(`${errorDetail.description} (${orderData.debug_id})`)
246249
} else if (!orderData.purchase_units) {
247250
throw new Error(JSON.stringify(orderData))
248251
} else {
@@ -263,16 +266,26 @@ async function initializePayPal (selector: string | HTMLElement) {
263266

264267
exponentialPseudoCoinBalanceCheck()
265268
}
266-
},
269+
} finally {
270+
initializePayPal_Subscription()
271+
}
272+
},
273+
274+
onError (error) {
275+
const message = []
267276

268-
onError (error) {
269-
Notification('An error with PayPal happened. More info in console.')
270-
console.log(error)
277+
for (const [key, value] of Object.entries(error)) {
278+
message.push(`${key}: ${value}`)
271279
}
272-
}).render(selector)
273-
} catch (e) {
274-
console.error(e)
275-
}
280+
281+
Notification(`An error with PayPal happened. More info in console. ${message.join(', ')}`)
282+
console.log(error)
283+
},
284+
285+
onCancel () {
286+
initializePayPal_Subscription()
287+
}
288+
}).render(selector)
276289
}
277290

278291
const sleep = (delay: number) => new Promise((r) => setTimeout(r, delay))

0 commit comments

Comments
 (0)